First things first, the declaration for the operator==
that you have(inside the class) is for a non-member nontemplate operator. So you can't implement it the way you're doing outside the class.
There are different ways of solving this.
Method 1
One way to solve this is by making the overloaded operator==
a template and defining it inside the class as shown below. Note that the operator==
is still a non-member.
Also note the use of typename
and template
keyword to tell the compiler that Iterator
is a type and a template. This is also explained here.
template<typename A>
struct Container{
template<class B>
class Iterator {
public:
explicit Iterator(B value) : value_(value) {};
//definition for a nonmember template version
//------------------vvv-------------vvv-------->default arguments used
template<typename U = A, typename V = B>
//---------------------------vvvvvvvv---------->typename used here
friend bool operator==(const typename Container<U>::template Iterator<V>& lhs,
const typename Container<U>::template Iterator<V>& rhs)
//--------------------------------------------------^^^^^^^^------------------>template used here
{
return lhs.value_ == rhs.value_;;
}
private:
B value_;
};
};
Container<int>::Iterator<double> it1{42.0}, it2{42.0};
int main()
{
assert(it1 == it2);
}
Working demo.
Method 2
Second option is to keep the opearator==
as a nontemplate as shown below:
template<typename A>
struct Container{
template<class B>
class Iterator {
public:
explicit Iterator(B value) : value_(value) {};
//declaration for a nonmember nontemplate version
//---------------------------vvvvvvvv------------------------------------------>typename used here
friend bool operator==(const typename Container<A>::template Iterator<B>& lhs,
const typename Container<A>::template Iterator<B>& rhs);
//--------------------------------------------------^^^^^^^^------------------>template used here
private:
B value_;
};
};
//implement the nonmember nontemplate version
bool operator==(const Container<int>::Iterator<double>&lhs, const Container<int>::Iterator<double>&rhs)
{
return lhs.value_ == rhs.value_;
}
Container<int>::Iterator<double> it1{42.0}, it2{42.0};
int main()
{
assert(it1 == it2);
}
Working demo.