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!
}
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.