2016-05-15 16 views
2

明らかに、std::threadコンストラクタに値の参照を渡すことは可能です。私の問題はcppreferenceのこのコンストラクタの定義にあります。std :: threadコンストラクタがrvalue参照を検出する方法は?

template< class Function, class... Args > 
explicit thread(Function&& f, Args&&... args); 

新しいはstd ::スレッドオブジェクトを作成し、 実行スレッドに関連付ける:それは、このコンストラクタがいることを言います。私の知る限り確認することができますよう

template <class T> 
typename decay<T>::type decay_copy(T&& v) { 
    return std::forward<T>(v); 
} 

:まずコンストラクタコピーは/すべての引数(両方 関数オブジェクトfと、すべての引数...)スレッドアクセスするためのストレージを かのように機能によりを移動します。

std::is_same<int, std::decay<int&&>::type>::value 

がtrueを返します。つまり、std::decay<T>::typeは引数の右辺参照部分を削除します。それではどのようにstd::threadコンストラクタがlvalueまたはrvalue参照によって渡される引数を知っていますか?すべてT&T&&std::decay<T>::type

+0

"タイプTへの左から右への値、配列からポインタ、および関数からポインタへの暗黙の変換を適用し、cv修飾子を削除し、結果の型をメンバのtypedef型" http:// en.cppreference.com/w/cpp/types/decay - 参照が削除される場所はどこですか? – xaxxon

+0

@xaxxonあなたは ':: type'がありません。 –

+0

@ T.C。削除されました - しかし、なぜ彼らは同じですか? – xaxxon

答えて

2
auto s = std::decay_copy(std::string("hello")); 

によってTに変換されますのでと同等です:

template<> 
std::string std::decay_copy<std::string>(std::string&& src) { 
    return std::string(std::move(src)); 
} 

std::string s = decay_copy<std::string>(std::string("hello")); 
+0

はC++ですか?私は関数名を<>で宣言したことはありません – xaxxon

+0

@ xaxxon多かれ少なかれ。テンプレート拡張の結果を実証しようとしています。 –

1

これは完璧な転送の共通の問題です。関数のrvalueに関する情報を復元するには、std :: forward std::forwardを使用する必要があります。値のタイプの検出に興味がある場合は、value_categoryをお読みください。コンパイル時に、コンパイラがrvalue、xvalue、lvalue、prvalue、gvalueをどのように認識するかについての説明があります。それは完全にdecay_copy(または同等)にそのパラメータを転送するために使用する、何FunctionArgs...ている知っているので、

3

std::threadコンストラクタは、引数の値カテゴリを知っています。

実際のスレッド関数は値カテゴリを認識しません。これは、常にrvalue引数で呼び出されます。fargs...のコピーはスレッドに対してローカルであり、他の場所では使用されません。

関連する問題