2016-10-18 4 views
3

に 'D' から引数を変換することはできません:、typeid(D)に基づいて辞書からC++ - のstd ::崩壊<T>とstd :: make_tuple <D>は - 私はこのコードを持っている 'D &&'

template <typename T> 
void someFunction(){ 
    typedef std::decay<T>::type D; 

    D val = GetValue<D>(); 
    std::tuple<D> t = std::make_tuple<D>(val); 

    //... tuple is stored outside this scope in global variable 
} 

GetValue<D>()戻り値を正常に動作しており、MyDataDに戻します。次の問題のある行をコメントアウトすると、テストしました。下記の問題を参照してください。

私はこれをコンパイルする場合、T = const MyData &のために私はこの

error C2664: 'std::tuple<MyData > std::make_tuple<D>(D &&)': cannot convert argument 1 from 'D' to 'D &&' 

なぜこのエラーが生成され、それを削除する方法を得ましたか。テンプレートTがrefdされていても、私のタプルに非ref値だけを保存したいのです。

ので、私はそれがstd::make_tuple<D>(std::forward<D>(val))を使用することにより、コンパイルを得ることができますが、それは私の移動のctorを呼び出し、valは方法の終わりと、その内部データで破壊されたので、私は、コピーctorのをCALしたい​​とctorのは、ちょうどそれらを移動する移動します彼らはなくなった。

+1

私はコンストラクタをコピーの両方を呼び出す誤っ避け、移動したい見ることができますが、あなたの移動のコンストラクタがinvalidingする必要がありますこの問題を防ぐために元のオブジェクト。それができない場合は、移動コンストラクタのほとんどの使用が壊れるので、それを削除してください。 – Guvante

答えて

5

make_tuplemake_pairに明示的なテンプレートパラメータを渡すべきではありません。彼らの能力は、タイプを推論する能力と、それらを崩壊させ、参照ラッパーをアンラッピングする能力に正確にあります。

次のように動作するはずです:

std::tuple<D> t = std::make_tuple(std::move(val)); // forward is superfluous here 

をか、いっそのこと:

auto t = std::make_tuple(GetValue<D>()); 
+0

また、 'std :: tuple 'を 'auto'に置き換えることは良い考えです。 – Yakk

+0

@krzaq OKをコンパイルしますが、コードを1行ずつステップすると、私はまだmove ctor( 'MyData :: MyData(MyData && other){}')になります。 –

+0

@MartinPerry:コピーを呼び出す限り後で移動コンストラクタを呼び出すコンストラクタはうまくいきます(コピーを移動しているだけなので)。 'GetValue ()'を 'val'に格納すると、コピーコンストラクタを呼び出す必要があります。 – Guvante

関連する問題