static_cast <t>对T&amp ;?

时间:2016-06-22 13:12:06

标签: c++ casting reference rvalue static-cast

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

在代码中:

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

static_cast只是构建一个R值int吗?它和电话之间的区别是什么:

replace(begin(foo), end(foo), int{foo.front()}, 13);

修改

根据答案推断static_cast 确实似乎构建了一个R值inthttp://ideone.com/dVPIhD

但是这段代码在Visual Studio 2015上工作。这是编译器错误吗?在此测试:http://webcompiler.cloudapp.net/

2 个答案:

答案 0 :(得分:7)

  1. 是的,它与int{...}相同,除非.front()返回了需要缩小转化的类型。在这种情况下,int(...)将是相同的。

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

  3. 注意,由于替换操作修改了前面的元素,因此消除了强制转换会导致未定义的行为,这可能会导致std::replace中断。

    我会用

    template<class T>
    std::decay_t<T> copy_of(T&& t){return std::forward<T>(t); }
    
    我自己在这里。

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

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

    您可以使用compiler flag (/Zc:rvalueCast)使MSVC不再破坏您的代码。

答案 1 :(得分:5)

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

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

template <class ForwardIterator, class T>
  void replace (ForwardIterator first, ForwardIterator last,
                const T& old_value, const T& new_value)

也通过引用获取第三个参数。因此,通常可以通过算法更改向量的第一个元素,因此算法对向量的其他元素的处理可能是不正确的。

使用static_cast创建临时对象,不会被算法更改因此,向量的所有元素的处理都是正确的。

就我而言,我建议在这种情况下使用关键字auto的C ++提案。例如

replace(begin(foo), end(foo), auto( foo.front() ), 13);