I want to define freestanding operators (op==, op<, etc.) for my iterator class, but I'm struggling with the proper syntax:
template<class A>
class Container {
public:
template<class B>
class Iterator {
public:
explicit Iterator(B value) : value_(value) {};
friend bool operator==(const Iterator& lhs, const Iterator& rhs);
private:
A value_;
};
};
// Fails to compile:
template<class A>
template<class B>
bool operator==(const typename Container<A>::Iterator<B>& lhs, const typename Container<A>::template Iterator<B>& rhs) {
return lhs.value_ == rhs.value_;
}
Container<int>::Iterator<double> it1{42.0};
Container<int>::Iterator<double> it2{42.0};
assert(it1 == it2);
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 theoperator==is still a non-member.Also note the use of
typenameandtemplatekeyword to tell the compiler thatIteratoris a type and a template. This is also explained here.Working demo.
Method 2
Second option is to keep the
opearator==as a nontemplate as shown below:Working demo.