static_cast <T>对T&做了什么?

Jon*_*Mee 7 c++ casting reference rvalue static-cast

所以我问了这个问题,我正在修补它通过解决它static_cast.(顺便提一下,它确实解决了问题,我只是不确定我是否理解为什么.)

在代码中:

vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), static_cast<int>(foo.front()), 13);
Run Code Online (Sandbox Code Playgroud)

static_cast简单地构建一个R值int?它和电话之间有什么区别:

replace(begin(foo), end(foo), int{foo.front()}, 13);
Run Code Online (Sandbox Code Playgroud)

编辑:

作为推断的答案static_cast 似乎构成一个R值int:http://ideone.com/dVPIhD

但是这个代码不上的Visual Studio 2015年工作,这是一个编译器错误?在这里测试:http://webcompiler.cloudapp.net/

Yak*_*ont 7

  1. 是的,int{...}除非.front()返回需要缩小转换的类型,否则它是相同的.在那种情况下,int(...)将是相同的.

  2. 在程序员错误的情况下,静态转换稍微不太可能做一些危险的事情,比如将指针转换为int而不是int(...).

注意取消强制转换会导致未定义的行为,因为前面的元素被替换操作修改,并且可能会中断std::replace.

我会用

template<class T>
std::decay_t<T> copy_of(T&& t){return std::forward<T>(t); }
Run Code Online (Sandbox Code Playgroud)

我在这里.

至于为什么这不适用于MSVC ......

MSVC可以帮助您将类型变量转换T为a T并继续执行任何操作.这会打破你的代码.

有一个编译器标志(/ Zc:rvalueCast)可用于使MSVC不再破坏您的代码.

  • @Yakk:当然,我明白了,但是如果他们建议打开标志,它应该默认开启.这样他们就每个其他编译器的行为打破了"遗留"行为!_need_遗留行为的用户应该被要求查找并打开它.IMO.在文档中,这似乎是一个非常奇怪的矛盾. (3认同)
  • _"默认情况下,/ Zc:rvalueCast已关闭.为了保持一致性并消除使用强制转换的错误,我们建议您使用/Zc:rvalueCast."_到底是什么 (2认同)

Vla*_*cow 5

成员函数front返回对非空向量的第一个元素的引用.

另一方面,标准算法replace声明为

template <class ForwardIterator, class T>
  void replace (ForwardIterator first, ForwardIterator last,
                const T& old_value, const T& new_value)
Run Code Online (Sandbox Code Playgroud)

通过引用获取第三个参数.因此,通常可以通过算法改变矢量的第一元素,并且因此算法对矢量的其他元素的处理可能是不正确的.

使用static_cast创建一个临时对象,并且算法不会更改它.因此,向量的所有元素的处理都是正确的.

至于我,那么我建议auto在这种情况下使用关键字的C++提议.例如

replace(begin(foo), end(foo), auto( foo.front() ), 13);
Run Code Online (Sandbox Code Playgroud)