是否存在std :: exchange无法在std :: vector :: reference上运行的技术原因,还是GCC和Clang实现中的错误? With MSVC it compiles fine。
我有这样的设置(最小示例)
struct Manager
{
std::vector<bool> lifeTimes;
//Should return the state before trying to kill it
bool kill(std::size_t index)
{
return std::exchange(lifeTimes[index], false);
}
};
std :: exchange将使它成为一个非常不错的班轮,但GCC抱怨:
错误:无法将类型'std :: _ Bit_reference&'的非常量左值引用绑定到类型为'std :: vector :: reference'的右值{aka'std :: _ Bit_reference'}
因此,它似乎抱怨false
since only the second parameter is an rvalue
答案 0 :(得分:2)
这不是错误,MSVC会编译您的代码,因为它具有扩展功能,可以将临时对象(Rvalue)绑定到非常量Lvalue引用。
以下代码使用MSVC编译:
void foo(int& i) {}
foo(20); // you are passing Rvalue and it is bound to Lvalue reference
当您添加const
来引用时,以上代码无法在G ++或CLang下编译
const Lvalue,它可以正常工作:
void foo(const int&){}
foo(20); // you can bind Rvalue to const Lvalue reference
关于向量的几句话。 operator[]
代表vector<T>
,其中T
是除布尔值以外的所有类型,返回T&
:
T& vector<T>::operator[](index) // where T is not bool
对于bool
向量类模板具有特殊性。存储bool
的值以保留一位空间,因为您不能为一位使用地址运算符,vector<bool>::operator[](index)
无法返回引用。 vector<bool>
具有内部的 proxy 类,该类可操纵位(将该类称为 reference )。
vector<bool>::reference vector<bool>::operator[](index)
^^^^^^^^^
您看到的proxy 对象是按值传递的。 因此,当您致电
return std::exchange(lifeTimes[index], false);
您正在将临时对象(Rvalue)传递给exchange
,后者通过引用非常量Lvalue来获取第一个参数。这就是G ++丢弃此代码的原因。如果要编译它,则可以显式创建 proxy 类的Lvalue对象并将其传递:
bool kill(std::size_t index)
{
std::vector<bool>::reference proxyForBit = lifeTimes[index];
return std::exchange(proxyForBit, false);
}