Consider this very simple example, where I have template wrapper class for which are defined operators:
template <class T>
struct W {
W(const T&) {}
};
template <class T>
T operator + (const W<T>& w1, const W<T>& w2) { return T(); }
And this surprisingly cannot match for wrapped type, with simple error from gcc4.5.1 that cannot find operator + (A,A)
:
struct A {};
int main() {
A a1, a2;
A a3 = a1 + a2;
}
I've tried to find the reason by testing non template wrapper, but this version works:
struct A {};
struct WA {
WA(const A&) {}
};
A operator + (const WA& w1, const WA& w2) { return A(); }
int main() {
A a1, a2;
A a3 = a1 + a2;
}
What is the reason of such difference of arguments matching, and what to do to make template version works?
[UPDATE]
I took your answers into consideration, and I've changed the example to be a little opposite way, still with the same results - template version is complaining for missing operator +, while non template works fine. Now I have explicit cast operator to explicit wrapper class:
template version
template <class T>
struct W {
};
template <class T>
T operator + (const W<T>& w1, const W<T>& w2) { return T(); }
struct A {
operator W<A>() const { return W<A>(); }
};
not template
struct WA {
};
struct A {
operator WA() const { return WA(); }
};
A operator + (const WA& w1, const WA& w2) { return A(); }
I am trying to avoid this solution:
A a3 = W(a1) + W(a2);
No hope for this to work?
A a3 = a1 + a2;