1

私はオーバーロードされたメソッドを持っています:

    template<typename AnyType>
    void AnyFunc(AnyType &t);

    template<typename AnyType>
    void AnyFunc(AnyType &&t);

ポインターを保持する呼び出し元があり、関数のいずれかを使用したい:

    MyType* ptr=new MyType();
    AnyFunc(*ptr);

最後の行でコンパイル エラーが発生します: AnyFunc のあいまいなオーバーロード

必要な機能を選択するにはどうすればよいですか? 簡単なケースでは、次を使用します。

    AnyFunc(std::move(*ptr)); 

を選択しますがvoid AnyFunc(AnyType &&t);、これは私が望むものではありません。void AnyFunc(AnyType &t);その方法が必要 です。

4

2 に答える 2

5

T&& v(はテンプレート パラメータです) があるときはいつでもT、いわゆるユニバーサル リファレンスがあります。右辺値だけでなく、左辺値にバインドします。欲張りなテンプレです。それは得ることができるものは何でも取り、何も返さないでしょう。

貪欲なテンプレートが関係しているときにオーバーロードするのは、自分が何をしているのかを正確に理解していない限り、悪い考えです。

ユニバーサル参照では、多くの場合、左辺値と右辺値を特別に区別する必要はありません。パラメータと値カテゴリだけstd::forward<T>(v)が伝播されます。

于 2012-11-30T16:36:04.530 に答える
1

修正する必要はありません。コードは C++11 に準拠しています。これらのケースの標準では、非ユニバーサル参照取得テンプレートは「より特殊化」されており、優先されると述べています。

したがって、呼び出しは最初のテンプレートを選択する必要があります。最初のテンプレートを削除すると、2 番目のテンプレートが使用されます。これに似ています

// "universal" with respect to const qualification
template<typename T>
void f(T &);

template<typename T>
void f(const T&);

これで、2 番目のテンプレート インスタンスが呼び出されます。これは、両方のインスタンスがconst int&パラメーターの型を持っている一方で、2 番目のインスタンスがより特殊化された関数テンプレートに関連付けられているためです。

const int a = 0;
f(a);

あなたの場合も同じです。const と lvalue/rvalue のすべての組み合わせで機能するという意味で、「完全」であることに注意してください

  • const 左辺値. どちらもconst U&パラメータとして持っていますが、T&一方はより特殊化されているため、半順序で取得されます。
  • non-const lvalue、あなたの場合。T&1つはU&パラメータとして、もう1つはパラメータとしてT&&持ってU&いますが、T&1つはより特殊化されているため、半順序で取得されます。
  • const 右辺値。1T&つはconst U&パラメータとして、T&&もう1つはパラメータとして持ってconst U&&います。左辺値参照よりも右辺値をバインドするには、右辺値参照を使用することをお勧めします。したがって、T&&1 つはオーバーロードの解決だけで取得されます。
  • 非 const 右辺値。1T&つはU&パラメータとして持っています。非 const 左辺値参照は、右辺値にバインドできません。したがって、T&&タイプを持つものは、オーバーロードの解決のみによってU&&選択されます。
于 2012-11-30T22:09:14.000 に答える