如何为嵌套类模板实现独立运算符



我想为迭代器类定义独立运算符(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==仍然是非成员。

还要注意使用typenametemplate关键字来告诉编译器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);
}

工作演示。

最新更新