2017-09-01 5 views
2

Iは転送基準は、上記の機能は、両方のLを取ることができることを意味し、このようなC++転送基準と右辺値参照

template <class T> void foo(T&&); 

のように、「CV-修飾されていないテンプレートパラメータに右辺値参照」であることを理解します値とr値の参照。

私には分かりません。上記のコードで

template <class T> 
class A 
{ 
    template <class U> 
    void foo(T&& t, U&& u) 
    { 
     T t2(std::forward(t)); // or should it be std::move(t)? is T&& forwarding or r-value reference 
     U u2(std::forward(u)); // or should it be std::move(u)? I believe U&& is forwarding reference 
    } 
}; 

はT & &及びUの両方が& &転送参照ですか?

は、私は(VS2015コンパイラ)をテストするためのいくつかのコードを書いた:

class A 
{ 
public: 
    A(){}; 
    A(const A& rhs) 
    { 
     std::cout << "calling 'const A&' l-value" << std::endl; 
    } 

    A(A&& rhs) 
    { 
     std::cout << "calling ' A&&' r-value" << std::endl; 
    } 

}; 

template <class T> 
class Test 
{ 
public: 
    void test1(T&& t) 
    { 
     T t2(std::forward<T>(t)); 
    } 

    template <typename X> 
    void test2(X&& x) 
    { 
     T t2(std::forward<T>(x)); 
    } 

}; 

void main() 
{ 
    A a; 
    Test<A> test; 
    test.test1(A()); 
    test.test1(std::move(a)); 
    //test.test1(a); // this doesn't compile. error: cannot convert argument 1 from 'A' to 'A &&', You cannot bind an lvalue to an rvalue reference 

    test.test2<A>(A()); 
    test.test2<A>(std::move(a)); 

    //test.test2<A>(a); // this doesn't compile. error: cannot convert argument 1 from 'A' to 'A &&', You cannot bind an lvalue to an rvalue reference 
} 

I(a)はそのtest.test1を期待していました。 test.test2(a)は、参照を転送している場合はコンパイルする必要がありますが、どちらもコンパイルする必要はありません。

誰かが私にこれを説明できますか?ありがとう!

編集 --------------おかげで、みんな----------- リチャードとArtemyは正しいです。

+2

VS2015のツールチェーンが 'void main()'を受け入れるのかどうかは関係ありません。本当に ? – WhozCraig

+0

あなたの最後の閉じたケースでは、Uは推論されないので、あなたのケースはコンパイルされません。それをdeducibleにするには、test.test2(a)と呼んでください。そして内部テスト2は、

答えて

2

最初はほとんど誰もが狐を抱く大きな問題です。この例では

template <class T> 
class A 
{ 
    template <class U> 
    void foo(T&& t, U&& u); 
}; 

Tは(テンプレートをインスタンス化するときに明示的に定義する)推測されていません。

Uは、引数uから推測されているため、これが導かれます。

したがって、ほとんどの場合、それは次のようになります

std::move(t); 
std::forward<U>(u); 
+0

BTW 'std :: forward (t);'と同じになります( '' std :: move(t); ''となります)。 – Jarod42

2

はT & &及びU & &転送参照の両方がありますか?

Uが推測されている唯一のテンプレート引数であるため、いいえ、唯一U&&は、フォワーディング参照です。 Aをインスタンス化するときにTが既に選択されていました。

関連する問題