所以我问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值int
:http://ideone.com/dVPIhD
但是这段代码不在Visual Studio 2015上工作。这是编译器错误吗?在此测试:http://webcompiler.cloudapp.net/
答案 0 :(得分:7)
是的,它与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
并继续执行任何操作。这会打破你的代码。
您可以使用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);