似乎添加默认构造函数会阻止调用emplace_back并产生错误消息:"静态断言失败:类型不可分配"(gcc 5.3 with -std = c ++ 14).这是一个简单的代码,说明了这个问题:
class A {
public:
int a;
A() = default;
A(int a) {
this->a = a;
}
A(A const & a) = delete;
A& operator =(A const & a) = delete;
A(A && a) = default;
A& operator =(A && a) = default;
};
int main() {
A a(4);
std::vector<A> vec;
vec.emplace_back(std::move(a)); // Error: type is not assignable
return 0;
}
Run Code Online (Sandbox Code Playgroud)
删除默认构造函数时,错误消失了!此外,如果定义了默认构造函数(即使它什么都不做),错误也会消失:
class A {
public:
int a;
A() {
}
A(int a) {
this->a = a;
}
A(A const & a) = delete;
A& operator =(A const & a) = delete;
A(A && a) = default;
A& operator =(A && a) = default;
};
int main() {
A b;
A a(4);
std::vector<A> vec;
vec.emplace_back(std::move(a)); // Error gone
return 0;
}
Run Code Online (Sandbox Code Playgroud)
似乎"A()=默认;" 是导致问题的原因.这是编译器的一部分正常行为还是一个错误?
T.C*_*.C. 15
这是一个libstdc ++ bug(编辑:报告为bug 69478).
简而言之,std::vector与此相关的libstdc ++ 使用std::uninitialized_copy(与移动迭代器配对)在重新分配时移动元素,std::copy如果类型是微不足道的,并且迭代器的引用类型是可分配的(即,概念上使用的赋值运算符是可以使用).
然后,std::copy指向普通类型的指针(或者在我们的例子中,move_iterator包装指针)又被优化为一个memmove与检查相结合的调用is_copy_assignable.当然,在这种情况下检查是错误的,因为uninitialized_copy与移动迭代器配对,只需要移动可构造的东西.
如果您没有默认构造函数或者默认构造函数是用户定义的,那么该类并不简单,因此您不会遇到触发此错误的代码路径.
| 归档时间: |
|
| 查看次数: |
528 次 |
| 最近记录: |