1

演算子が定義されているテンプレートラッパークラスがあるこの非常に単純な例を考えてみましょう:

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;
4

2 に答える 2

4

テンプレート引数の推定は、オーバーロード解決の前に行われます。ただし、テンプレートの引数推定では暗黙的な変換が考慮されないため、テンプレート化された演算子は考慮されません。

暗黙的な変換は、オーバーロードが選択されたにのみ適用されます。

しかし、あなたは言うことができA a3 = W(a1) + W(a2);ます。

于 2012-10-05T11:58:20.210 に答える
2

最初の例は、標準ではテンプレートで失敗する必要があると規定されているため、失敗します。引数に依存する名前の検索には潜在的な問題があり、テンプレートはそれらの問題を悪化させます。これを回避する1つの方法は、テンプレートの使用について明示的でない限り、そのようなルックアップからテンプレートを除外することです。これは、C ++ 03標準、セクション14.8.1のパラグラフ6からの関連テキストです。

単純な関数名の場合、関数名が呼び出しのスコープ内に表示されていない場合でも、引数依存のルックアップ(3.4.2)が適用されます。これは、呼び出しがまだ関数呼び出し(3.4.1)の構文形式を持っているためです。ただし、明示的なテンプレート引数を持つ関数テンプレートが使用されている場合、呼び出しのポイントにその名前の関数テンプレートが表示されていない限り、呼び出しには正しい構文形式がありません。そのような名前が表示されない場合、呼び出しは構文的に整形式ではなく、引数に依存するルックアップは適用されません。そのような名前が表示されている場合は、引数依存のルックアップが適用され、他の名前空間に追加の関数テンプレートが見つかる場合があります。

更新:
質問は追加情報で編集されました。

私はこの解決策を避けようとしています:
A a3 = W(a1) + W(a2);

なぜ、正確に、あなたはその状況を避けようとしているのですか?このコードは、プログラミングの2つの重要なルールに違反しています。

  1. あなたのコードを維持する次の人があなたがどこに住んでいるかを知っている殺人マニアであるかのようにコードします。
  2. 驚き最小の原則。

テンプレート以外のバージョンでさえ、これらのルールに違反しています。a1+a2無関係なクラスへの(非表示の)変換によって計算します。Wそのクラスは、ではなくoperator+を返します。これは驚き最小の原則ではありません。控えめに言っても、これは驚くべきことです。変換を明示的にする方が良いアプローチだと思いませんか?AW

引数依存のルックアップは非常に強力なツールですが、この機能に関連する問題がたくさんあります。ADLを自動型変換と組み合わせると、問題が拡大します。自動型変換とテンプレートを組み合わせると、混乱が生じます。標準委員会は十分であると判断しました。変換を明示的にしない限り、やりたいことを行うことはできません。

于 2012-10-05T12:05:18.410 に答える