【发布时间】:2016-01-25 21:08:28
【问题描述】:
似乎添加默认构造函数会阻止调用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;
}
删除默认构造函数时,错误消失了!此外,如果定义了默认构造函数(即使它什么都不做),错误也会消失:
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;
}
似乎 "A() = default;"是导致问题的原因。 这是编译器部分的正常行为还是错误?
【问题讨论】:
-
clang 显示与 gcc 相同的行为
-
代码在c++11下使用gcc 4.7.2编译良好span>
-
影响课堂的琐碎性。
-
如果您使用 libc++,@jaggedSpire clang 会编译代码。这看起来像是 libstdc++ 的一个错误,它可能将针对琐碎类型的
emplace_back优化为memcpy调用,并且该调用链涉及调用一个断言该类型是可复制分配的函数。 -
@rustyx,
A() = default;可能是微不足道的,但A() {}绝对不是。这可能会影响优化(在这种情况下,尽管 std::lib 的优化尝试存在错误)。