c++templatesoperator-overloadingtype-members

operator<< overload for a member type in a template class in C++


In the code below, I have a template class with a member type(struct Element). I want to overload operator<< for that member type. However, the code won't compile.

I would appreciate it if someone could point out where I am going wrong?

include <iostream>
using namespace std;

// fwd decl
template<class T> class CC;

// operator<< overload template for member type CC<T>::Element
template<class T>
ostream& operator<<(ostream& os, const typename CC<T>::Element& elm) {
    return os << elm.val1 << "/" << elm.val2;
}

template<class T>
class CC
{
public:
    struct Element {    // type member
        int val1;
        int val2;
    };

    template<typename U>
    friend ostream& operator<<(ostream& os, const typename CC<U>::Element& elm);
};

int main() {
    CC<int>::Element elm{0,0};
    cout << elm << endl;     // does not compile due to this!
}

Solution

  • Template arguments can't be deduced from a nested entity (the short explanation: the type may be seame for different template instantiations). That is, the declaration

    template<typename U>
    ostream& operator<<(ostream& os, const typename CC<U>::Element& elm);
    

    whether for a friend or not is never considered because the type U can't be deduced. You can fix the problem by making the friend operator a non-template:

    // ...
    friend ostream& operator<<(ostream& os, const Element& elm) { ... }
    // or
    friend ostream& operator<<(ostream& os, const CC<T>::Element& elm) { ... }
    // ...
    

    The function will need to be implemented in its declaration, though.