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