我想为迭代器类定义独立运算符(op==、op<等(,但我很难找到正确的语法:
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);
首先,您拥有的operator==
(类内(的声明是针对非成员非模板运算符的。所以你不能像在课堂外那样实现它。
解决这个问题有不同的方法。
方法1
解决这一问题的一种方法是将重载的operator==
作为模板,并在类中定义它,如下所示。注意,operator==
仍然是非成员。
还要注意使用typename
和template
关键字来告诉编译器Iterator
是一个类型和模板。这一点在这里也有解释。
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);
}
工作演示。
方法2
第二种选择是将opearator==
保持为非模板,如下所示:
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);
}
工作演示。