给出以下代码:
template<class T>
class TemplateClass {
T val;
public:
TemplateClass(T val) :
val(val) {
}
TemplateClass(const TemplateClass& tc) = default;
TemplateClass& operator=(const TemplateClass& tc) = default;
class Ele {
T x;
public:
Ele(T x) :
x(x) {
}
template<class S>
friend bool operator==(const typename TemplateClass<S>::Ele& e1,
const typename TemplateClass<S>::Ele& e2);
};
};
template<class T>
bool operator==(const typename TemplateClass<T>::Ele& e1,
const typename TemplateClass<T>::Ele& e2) {
return e1.x == e2.x;
}
int main() {
TemplateClass<int>::Ele e1(4);
TemplateClass<int>::Ele e2(3);
if (e1 == e2) { // *********** error
std::cout << "ok" << std::endl;
}
}
我收到以下错误:
与“
operator==
”不匹配(操作数类型为“TemplateClass<int>::Ele
”和“TemplateClass<int>::Ele
”)
有人可以告诉我如何解决它,这是什么问题?
答案 0 :(得分:2)
类型的嵌套名称属于non-deduced contexts:
1)嵌套名称说明符(范围解析运算符::的所有内容),该类型是使用限定ID指定的:
由于模板自变量推导失败,因此无法调用operator==
。模板参数无法推论。
您可以使其成为非模板函数,并在类定义中对其进行定义。例如
template<class T>
class TemplateClass {
...
class Ele {
...
friend bool operator==(const typename TemplateClass<T>::Ele& e1,
const typename TemplateClass<T>::Ele& e2) {
return e1.x == e2.x;
}
};
};
或使其成为非模板成员函数,则可以在类定义之外定义它们。例如
template<class T>
class TemplateClass {
...
class Ele {
...
bool operator==(const typename TemplateClass<T>::Ele& e2) const;
bool operator!=(const typename TemplateClass<T>::Ele& e2) const;
};
};
template<class T>
bool TemplateClass<T>::Ele::operator==(const typename TemplateClass<T>::Ele& e2) const {
return x == e2.x;
}
template<class T>
bool TemplateClass<T>::Ele::operator!=(const typename TemplateClass<T>::Ele& e2) const {
return ! (*this == e2);
}
答案 1 :(得分:1)
除了此处的答案之外,您还可以使用friend injection technique来修复错误:
template<class T>
class TemplateClass {
// ...
class Ele {
// ...
friend bool operator==(const Ele& e1, const Ele& e2) {
return e1.x == e2.x;
}
};
};
请注意,这里根本不需要有问题的typename TemplateClass<S>::Ele
。