2015-09-27 9 views
6

私が理解するところでは、std::forward<T>(x)static_cast<T&&>(x)に相当します。両方が同じ持っている場合 C++ std :: forward <T> vs static_cast <T>

しかし、私が見たものから

は、 static_cast<T>(x)は、 static_cast<T>(x)を以下 code

私の質問に見られるように、同じことをやっているようだstd::forward<T>static_cast<T&&>(x)として実装されている理由はそのためではなく、効果?

+1

あなたは 'int 'で試してみませんでした。 – Quentin

+0

@Quentinその場合、常に左辺値を返します。 – Mikrosaft

+0

'static_cast 'は、参照を転送したいが値は転送しないため、 –

答えて

10

完全転送はr値参照のl値参照の両方を渡すことができるためです。あなたは、単にr値の参照を失っているstatic_cast<T>であなたの例では

T = int --> T&& = int&& 
T = int& --> T&& = int& && = int& 
T = int&& --> T&& = int&& && = int&& 

:これはreference collapsingを介して行われます。プリミティブ型の場合は正常に動作します(intは通常CPUレジスタ値をコピーしているため)。しかし、複雑な型の場合はひどいので、コピーctorsを介して一時オブジェクトを作成するためです。

+0

私はちょうどそれをチェックし、実際にはrvalueのコピーコンストラクタを呼び出しています。 しかし、なぜですか?私はrvalueをfunc()と呼ぶと、Tはint &&であると推測されるので、static_cast (x)はstatic_cast (x)になります。 なぜコピーを作成するのですか? – Mikrosaft

+2

'static_cast 'は参照を返すことができます:上記の答えはできないことを意味します。問題が1つの「ケース」でのみ発生することを明確にすることはできますか? – Yakk

+0

@Mikrosaft:いいえ、 'T 'は' int && 'に導くことはできません。' int'または 'int&'のいずれかになります。 – myaut

2

T&&は右辺値参照である場合には、Tは、static_cast<T>コピーない右辺値参照を行い、値です。

このコピーは、(参照と同様に)評価値の参照にバインドされますが、コピー/ムーブの呼び出しは不必要に呼び出される可能性があり、elisionの候補ではありません。

static_cast<T&&>一方、右値参照にキャストするだけです。

それ以外は同じです。

0

私はYakkに同意しますが、それはそれより悪いです。

void foo(const std::vector<int> &vec); 

template<typename T> 
void callFoo(T &&data) 
{ 
    foo(static_cast<T>(data)); 
} 

int main() 
{ 
    callFoo(std::vector<int>{/*...*/}); 
} 

これは常にコピーを作成します。置換された型がstd::vector<int>&&であっても、式としてdataがタイプstd::vector<int>の左辺値であるため、ではありません。 Tstd::vector<int> &&ではなく、std::vector<int>であることに注意してください。物語のモラル:標準ライブラリを使用すると、それは正しいことを行い、名前forwardstatic_cast<something>よりはるかに良い意図をキャプチャします。

関連する問題