2017-09-14 11 views
3

私は次の関数rvalueリファレンスまたは転送参照?

template <typename T> 
void do_something(T&& arg); 

のための関数のパラメータが転送参照であることを知っています。しかし、次のケースではそれはまだ転送参照または参照値参照ですか?

template <typename T> 
class MyClass 
{ 
    void do_something(T&& arg); 
}; 

まだ転送の参考資料だとは思いますが、わかりません。さらに私は、結果が私が意図したものでない場合、評価値参照またはそれぞれの転送参照を強制するために何ができるかを知りたい。

答えて

4

これは評価基準です。転送参照は、推測されたコンテキスト内にしか現れません。これは、クラステンプレートパラメータの右辺参照を受け付けるメンバ関数です。

ファンクションのテンプレート引数の控除を維持する場合は、転送参照を強制的に参照値にすることはできません。

template<typename T> struct identity { using type = T; }; 

template <typename T> void func(typename identity<T>::type&&); 
振り返ってみると

、実際に控除が、力を維持するための方法があります:あなたはすべての場所にテンプレート引数を指定して気にしない場合、これはいつもとしか右辺値参照を与えます右の値のみが受け入れられます(Simpleの答えには、自己文書化以外にも)。左辺値が渡された場合左辺値過負荷がより特化され

template<typename T> 
void func(T&) = delete; 

template<typename T> 
void func(T&& s) 
{ 
    // ... 
} 

:あなたは、削除された左辺値過負荷を提供することができます。そして、削除のために、いくらか明確なエラーメッセージが表示されます。

+1

decuced contextは、型が渡された引数から自動的に導出されることを意味しますか?私があなたを正しく理解していれば、それはクラス署名の一部であるため、Tは推論されません。 –

+0

@MartinKalbfuß - 正確に。あなたがdo_somethingのフリー関数版を呼び出すと、推測されるコンテキストがあります。 – StoryTeller

3

さらに私はあなたが常に推定されるコンテキスト(およびない転送参照)における右辺値参照をしたい場合は右辺値参照

を強制するために何を行うことができます、知っているように、あなたが使用することができますこの:その後、T意志、あなたはstd::string&&fooを呼び出すすなわち場合(

template< 
    typename T, 
    typename = std::enable_if_t<!std::is_lvalue_reference<T>::value> 
> 
using rval_ref = T&&; 

template<typename T> 
void foo(rval_ref<T> s) 
{ 
    // ... 
} 

fooだけ右辺値で呼び出すことができ、かつTは参照されませんstd::string)。

+0

悪くない。依存型を取り除き、左辺値の参照をブロックするためにSFINAEを使用しました。 +1 – StoryTeller

関連する問題