提问者:小点点

static_cast<T >对T做了什么


所以我问了这个问题,我正在通过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);

编辑:

根据答案推断,< code>static_cast似乎确实构造了一个R值< code > int :http://ideone.com/dVPIhD

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


共2个答案

匿名用户

>

  • 是的,它与int{…}相同,除非。front()返回了一个需要收缩转换的类型。在这种情况下,int(…)将是相同的。

    在程序员错误的情况下,静态转换做危险事情的可能性略低于int(…),例如将指针转换为int。

    请注意,消除强制转换会导致未定义的行为,因为前部元素被替换操作修改,这可能会破坏 std::replace

    我会使用

    template<class T>
    std::decay_t<T> copy_of(T&& t){return std::forward<T>(t); }
    

    我自己在这里。

    至于为什么这在MSVC中不起作用...

    MSVC可以帮助您将T类型的变量转换为T类型,然后继续不做任何事情。这会破坏您的代码。

    有一个编译器标志(/Zc:rvalueCast)可以让MSVC不再破坏你的代码。

  • 匿名用户

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

    另一方面,标准算法替换声明如下

    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);