31

次のようなものを宣言しますか

void foo(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }

理にかなっていますか?発信者はどのようにそれらを区別できますか? 私はもう試した

foo(9);  // Compiler complains ambiguous call.

int x = 9;
foo(x);  // Also ambiguous.

const int &y = x;
foo(y);  // Also ambiguous.
4

6 に答える 6

11

9その意図は、一時的な呼び出し (つまり) と「通常の」引数の受け渡しを区別することであると思われます。最初のケースでは、引数が後で破棄されることが明らかであるため、関数の実装で最適化を使用できる場合があります (整数リテラルではまったく意味がありませんが、ユーザー定義オブジェクトでは意味がある場合があります)。

ただし、現在の C++ 言語標準では、引数の「l/r-valueness」専用にオーバーロードする方法は提供されていません。関数に引数として渡される左辺値は暗黙的に参照に変換される可能性があるため、あいまいさは次のとおりです。やむを得ない。

C++11 では、同様の目的で新しいツールが導入されています —右辺値参照を使用すると、次のようにオーバーロードできます。

void foo(int x)        { ... }
void foo(const int &&x) { ... }

... そしてfoo(4)(引数として渡された一時的な r 値) は、コンパイラに 2 番目のオーバーロードをint i = 2; foo(i)選択させ、最初のオーバーロードを選択させます。

(: 新しいツールチェーンを使用しても、サンプルでケース 2 と 3 を区別することはできません!)

于 2011-03-28T21:37:07.360 に答える
6

テンプレートでこれを行うことができます:

template<typename T> void foo(T x) { ... }

次に、このテンプレートを値または参照で呼び出すことができます。

int x = 123;
foo<int>(x);  // by value
foo<int const&>(x);  // by refernce
于 2011-03-29T02:42:41.813 に答える
3

発信者はどのようにそれらを区別できますか?

この場合は区別できません。オーバーロードされた関数はどちらも、引数と同じのプリミティブ データ型を持ちます。また、参照による取得は、別の型ではカウントされません。

于 2011-03-28T21:34:41.867 に答える
1

コンパイラはできません。foo の両方の定義は、int のすべての「バリアント」に使用できます。

最初の foo では、int のコピーが作成されます。int のコピーは常に可能です。

2 番目の foo では、const int への参照が渡されます。任意の int を const int にキャストできるため、それへの参照も渡すことができます。

両方のバリアントがすべての場合に有効であるため、コンパイラは選択できません。

たとえば、次の定義を使用すると、状況が異なります。

void foo (int &x);

foo(9)const 以外の int 参照として 9 を渡すことはできないため、で呼び出すと最初の選択肢が使用されます。

別の例として、コピー コンストラクターがプライベートなクラスで int を置き換えると、呼び出し元は値のコピーを作成できず、最初の foo-variant は使用されません。

于 2011-03-28T21:37:39.037 に答える
1

C++ にはありません。Erlang や Haskell などの関数型言語は、パラメーター値に基づいて関数のオーバーロードを指定できるようにすることで、より近づきますが、C++ を含むほとんどの命令型言語では、メソッド シグネチャに基づいてオーバーロードする必要があります。つまり、各パラメーターの数と型、および戻り値の型です。

シグネチャのconstキーワードは、パラメーターの型を定義するのではなく、関数内での可変性を定義します。" const" パラメーターは、関数によって変更された場合、または を使用しない関数への参照によって渡された場合、コンパイラ エラーを生成しますconst

于 2011-03-28T21:33:54.910 に答える