右辺値参照を特定のオブジェクトまたはその一時コピーにバインドするための最良の方法は何ですか?
A &&var_or_dummy = modify? static_cast<A&&>( my_A )
: static_cast<A&&>( static_cast<A>( my_A ) );
(このコードは最近のGCC 4.6では機能しません…以前は機能していたことを思い出しますが、現在は常にコピーを返します。)
最初の行で、左辺値からx値にstatic_cast
変換します。my_A
(C++0x§5.2.9/1-3)static_cast
2行目の内側は左辺値から右辺値への変換を実行し、外側はこの値からx値を取得します。
名前付き参照は§12.2/5に従って条件付きで一時的にバインドされるため、これはサポートされているようです。同じトリックは、const
参照を使用してC++03でも同じように機能します。
同じことをあまり冗長に書くこともできません。
A &&var_or_dummy = modify? std::move( my_A )
: static_cast<A&&>( A( my_A ) );
今でははるかに短くなっています。最初の省略形は疑わしいです:move
単なる左辺値からx値から左辺値へのシャッフルではなく、オブジェクトに何かが起こっていることを示すことになっています。紛らわしいことに、関数呼び出しが一時から参照へのバインドを中断するため、のmove
後に使用することはできません。:
構文A(my_A)
はおそらくより明確ですがstatic_cast
、技術的にはCスタイルのキャストと同等です。
私はずっと行き、それを完全にCスタイルのキャストで書くこともできます:
A &&var_or_dummy = modify? (A&&)( my_A ) : (A&&)( A( my_A ) );
結局のところ、これがイディオムになるのであれば、それは便利である必要があり、static_cast
とにかく私を何からも実際に保護しているわけではありません。本当の危険はmy_A
、true
ケースに直接バインドできないことです。
一方、これは3回繰り返されるタイプ名によって簡単に支配されます。大きくて醜いtemplate-idに置き換えられた場合A
、私は本当に本当のショートカットが欲しいと思います。
(5回表示されているにもかかわらず、1回だけ評価されることに注意してくださいV
:)
#define VAR_OR_DUMMY( C, V ) ( (C)? \
static_cast< typename std::remove_reference< decltype(V) >::type && >( V ) \
: static_cast< typename std::remove_reference< decltype(V) >::type && > ( \
static_cast< typename std::remove_reference< decltype(V) >::type >( V ) ) )
マクロはハックですが、それが最良の選択肢だと思います。xvalueを返すため、少し危険です。したがって、参照の初期化以外では使用しないでください。
私が考えていなかった何かがあるに違いありません…提案?