将右值引用绑定到给定对象或其临时副本的最佳方法是什么?
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
第二行的内部执行左值到右值的转换,外部的从这个prvalue获得一个xvalue。
这似乎是受支持的,因为根据 §12.2/5,命名引用有条件地绑定到临时。相同的技巧在 C++03 中的工作方式与const
引用相同。
我也可以不那么冗长地写同样的东西:
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
。
另一方面,这很容易被重复三遍的类型名所支配。如果A
被替换为一个又大又丑的模板 ID,我真的想要一个真正的捷径。
(请注意,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,所以它不应该在引用初始化之外使用。
一定有什么我没有想到的……建议?