考慮這個非常簡單的例子,在那裏我有被定義運營商模板包裝類:爲什麼參數匹配適用於非模板版本,但不適用於模板版本?
template <class T>
struct W {
W(const T&) {}
};
template <class T>
T operator + (const W<T>& w1, const W<T>& w2) { return T(); }
這令人驚訝的無法比擬的包裝類型,從gcc4.5.1簡單的錯誤是無法找到operator + (A,A)
:
struct A {};
int main() {
A a1, a2;
A a3 = a1 + a2;
}
我試圖找到測試非模板包裝的原因,但這個版本的作品:
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;
}
這些參數匹配差異的原因是什麼,以及如何使模板版本起作用?
[更新]
我把你的答案考慮,我已經改變的例子是有點相反的方式,仍具有相同的結果 - 模板版本抱怨缺少運營商+,而非模板工作正常。現在我有明確的轉換操作員明確的包裝類:
模板版本
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>(); }
};
沒有模板
struct WA {
};
struct A {
operator WA() const { return WA(); }
};
A operator + (const WA& w1, const WA& w2) { return A(); }
我試圖避免這種情況的解決方案:
A a3 = W(a1) + W(a2);
沒有希望這個工作?
A a3 = a1 + a2;
所以編譯器是正確的,但這是我想要避免的。也許還有另外一種方法通過模板包裝實現'A a3 = a1 + a2'? – PiotrNycz
我已經對我的問題進行了更新。你的答案仍然適用? – PiotrNycz
@PiotrNycz:No;你仍然依靠隱式轉換。爲什麼不用「is_constructible_from」提供一個SFINAE-ed模板呢? –