12

VisualStudio2010およびVisualStudio2012がこのコードのコンパイルに失敗するのはなぜですか?

Codepad.org、Xcode、gcc、LLVM、Clangはすべて問題ありませんが、VisualStudioがベッドをうんちします。

struct S {
  template <class T> inline operator T () const { return T (); }
};
int main () {
  // NOTE: "S()" denotes construction in these examples
  struct F {
    void operator() (bool) { }
    static void toint (int) { }
    static void tostr (char const*) { }
  };
  bool b1 = S (); // Okay
  bool b2 (S ()); // Okay
  F () (S ());    // Okay
  F::toint (S ());// Okay
  F::tostr (S ());// Okay

  S () || false;  // Error: error C2676: binary '||' : 'vf::S' does
                  // not define this operator or a conversion to a type
                  // acceptable to the predefined operator
  return 0;
}

キーワードを追加してexplicitも、gccやclangの内容は変わりません。生成されるエラーメッセージは次のとおりです。

error C2676: binary '||' : 'S' does not define this operator or a
  conversion to a type acceptable to the predefined operator
4

2 に答える 2

3

少なくとも C++03 ではバグです (C++11 についてはわかりません)。

C++03 §13.3.1.2 のオーバーロード解決規則に従って、||ユーザー定義の||演算子が に対して定義されていないため、組み込み演算子が選択されSます。

§5.15/1 は次のように述べています。

演算子は||左から右にグループ化します。オペランドは両方ともbool(節 4) に暗黙的に変換されます。[...]

§12.3/2 は次のように述べています。

ユーザー定義の変換は、明確な場合にのみ適用されます (10.2、12.3.2)。[...]

§12.3/5:

ユーザー定義の変換は、明確な場合にのみ暗黙的に使用されます。[...] 関数オーバーロード解決 (13.3.3) は、変換を実行するための最適な変換関数を選択します。

§13.3.2/3:

第 2 にF、実行可能な関数であるためには、各引数に対して、その引数を の対応するパラメーターに変換する暗黙の変換シーケンス (13.3.3.1) が存在する必要がありますF

Sへのユーザー定義の変換を明確に定義しますbool。組み込みの||演算子は、オーバーロードの解決に実行可能な関数であり、それが唯一のものであるため、最適です。したがって、式は整形式です。

また、§4/3 も注目に値します。

宣言が「<code>T t=e;」の場合にのみ、式eを暗黙的に型に変換できます。Tいくつかの発明された一時変数t(8.5) の場合、整形式です。[...]

したがって、Visual Studio も statement に対してエラーを生成するかどうかに興味がありますbool b = S();

于 2012-11-24T17:48:06.227 に答える
0

ブール値への暗黙的な型キャストを禁止する場合、コンパイラは演算子 || があるかどうかを確認する必要があります。ブール値を取る定義済み。これは (できれば!) 定義されていません。ショートカットが壊れてしまうからです。したがって、彼は、グローバル || 演算子に対して定義された何かを与える変換演算子が定義されているかどうかを確認する必要があります。この問題は、変換演算子を bool、BOOL、または int に追加することで解決できますか (どれも同じです^^)...?

operator bool() {return this != null && this != 0xcccccccc;}

このBTWは単なるハックです。論理的に意味のある変換を提供する方がよいでしょう。

デバッグモードで初期化されていないメモリをマークする 0xcccccccc に対して定義された定数があることは確かですが、私はそれを知りません。

于 2012-11-24T16:43:35.790 に答える