2

is_callable<F, Args...>少し前に、トレイトを書きたいときに、いくつかのコードの次の動作に混乱しました。過負荷の解決では、非定数refによる引数を受け入れる関数は呼び出されませんよね?コンストラクターが必要なため、次のように拒否しないのはなぜTest&ですか?かかると思っていましたf(int)

struct Test {
  Test() { }

  // I want Test not be copyable from rvalues!
  Test(Test&) { }

  // But it's convertible to int
  operator int() { return 0; }
};

void f(int) { }
void f(Test) { }

struct WorksFine { };
struct Slurper { Slurper(WorksFine&) { } };
struct Eater { Eater(WorksFine) { } };

void g(Slurper) { }
void g(Eater) { } // chooses this, as expected

int main() {
  // Error, why?
  f(Test());

  // But this works, why?
  g(WorksFine());
}

エラーメッセージは

m.cpp: In function 'int main()':
m.cpp:33:11: error: no matching function for call to 'Test::Test(Test)'
m.cpp:5:3: note: candidates are: Test::Test(Test&)
m.cpp:2:3: note:                 Test::Test()
m.cpp:33:11: error:   initializing argument 1 of 'void f(Test)'

一方が機能するのにもう一方が機能しない理由を説明していただけますか?

4

2 に答える 2

3

過負荷解決は、指定された引数に最も近い関数を選択します。テストを提供しました。変換は必要ありません-ID変換が使用されます。したがって、関数解決はf(Test)を選択します。指定した右辺値からテストをコピーすることはできませんが、オーバーロードの解決はすでに成功しています...intへの変換はチェックされません。

g(Eater)タイプが完全に一致せず、ID変換が使用されず、コンパイラーが機能する変換ルーチンを見つける必要があるため、が選択されています。 g(Slurper)提供された引数から1つを作成できないためではありません。

「なぜこれが失敗しないのか:struct A { operator int(); }; void f(A&); void f(int); void g() { f(A()); }

f(A&)は、指定された引数に対して実行可能なオーバーロードではないためです。この場合、パラメーターは参照であり、tempsがnon-constにバインドされないという事実により、解決に影響を与えることができます。この場合、それは実行され、そのバージョンの関数は非候補になり、1つだけが残り、機能します。

于 2011-01-16T09:58:09.677 に答える
0

基本的に、過負荷の解決のために、タイプAのオブジェクトは、2つのいずれかのcv資格に関係なく、タイプAのオブジェクトに変換できると想定されています。

ドラフトn1905から:

13.3.3.1:オーバーロード。オーバーロード解決。最良の実行可能な関数。暗黙の変換シーケンス

6パラメータタイプが参照でない場合、暗黙の変換シーケンスは、引数式からのパラメータのコピー初期化をモデル化します。暗黙の変換シーケンスは、引数式をパラメーターの型の右辺値に変換するために必要なシーケンスです。[:パラメーターがクラスタイプの場合、これは第13節の目的で定義された概念的な変換です。実際の初期化はコンストラクターで定義されており、変換ではありません。— end note ]トップレベルのcv-qualificationの違いは、初期化自体に含まれ、変換を構成するものではありません。例】:タイプAのパラメーターは、タイプconst Aの引数から初期化できます。その場合の暗黙の変換シーケンスは、IDシーケンスです。const AからAへの「変換」は含まれていません。—終了例]パラメータにクラス型があり、引数式が同じ型の場合、暗黙の変換シーケンスはID変換です。[...]

于 2011-01-16T11:02:04.650 に答える