Reputation: 129
Given the following code:
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;
}
}
I get the following error:
no match for '
operator==
' (operand types are 'TemplateClass<int>::Ele
' and 'TemplateClass<int>::Ele
')
Can someone tell me how can I fix it and what is the problem?
Upvotes: 2
Views: 432
Reputation: 136485
In addition to the answers here, you can use friend injection technique to fix the error:
template<class T>
class TemplateClass {
// ...
class Ele {
// ...
friend bool operator==(const Ele& e1, const Ele& e2) {
return e1.x == e2.x;
}
};
};
Note that you do not need problematic typename TemplateClass<S>::Ele
here at all.
Upvotes: 1
Reputation: 172994
Nested name of a type belongs to non-deduced contexts:
1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:
So operator==
fails to be invoked because template argument deduction fails; template parameter can't be deduced.
You might make it a non-template function, and define it inside the class definition. e.g.
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;
}
};
};
Or make it non-template member function, then you might define them out of the class definition. e.g.
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);
}
Upvotes: 2