class A
{
int a;
public:
A(const A&) = delete;
A& operator=(const A&) = delete;
A() : a {0}
{ }
};
int main()
{
auto a = A {};
}
上面的代码没有编译,我得到以下错误:C2280'A :: A(const A&)':尝试引用已删除的函数
我正在使用visual studio 2015编译器。我的理解是使用成员初始化语法编译器应该直接使用默认构造函数,这是在没有auto时发生的情况,而在main中我使用A a{}
。所以我想知道在这种情况下与auto的交易是什么。
答案 0 :(得分:8)
auto a = A {};
仅在A
可复制或移动可构造时有效。您使用auto
这一事实无关紧要。
A a = A {};
。
声明一个复制构造函数 - 甚至是一个delete
d - 禁止隐式声明移动构造函数,因此类型A
既不是可复制构造也不是可构造的。如果添加行
A(A&&) = default;
到A
的主体,代码应该再次编译。
实际上,在这种情况下,编译器实际上不会调用任何副本或移动构造函数,只需在a
中构造对象即可。但语言规则要求它仍然必须拒绝有意义的代码,因为一段代码是否允许不应该依赖于可选的编译器优化。
此行为(很可能)在C ++ 17中change。
答案 1 :(得分:1)
您的理解是正确的,所以让我们一步一步看看这里发生了什么。
A {};
正如你所说,成员初始化语法,完全是犹太人。
auto a = (expression of some kind)
然后你正在构建auto a
。执行类型推断后,这相当于......
A a = (expression of some kind)
它看起来像一个复制构造函数。你删除了哪个。
答案 2 :(得分:-4)
你应该以这种方式使用自动:
auto a = new A();
如果您不想使用auto,这是c ++ 11方式:
A a{};