在Visual Studio 2013(版本12.0.31101.00更新4)中,此代码段已编译,没有错误。

class A
{
public:
   A(){}
   A(A &&){}
};

int main(int, char*)
{
   A a;
   new A(a);
   return 0;
}

在Visual Studio 2015 RC(版本14.0.22823.1 D14REL)中因此错误而编译时:
1>------ Build started: Project: foo, Configuration: Debug Win32 ------
1>  foo.cpp
1>c:\dev\foo\foo.cpp(11): error C2280: 'A::A(const A &)': attempting to reference a deleted function
1>  c:\dev\foo\foo.cpp(6): note: compiler has generated 'A::A' here
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我认为Visual Studio 2015附带的编译器生成了Copy构造函数并将其标记为=delete,因此出现错误C2280(顺便说一句,我找不到msdn.microsoft.com上的文档)。

现在,假设我有一个可以与Visual Studio 2013一起编译的代码库(之所以可以工作,因为它依赖于编译器自动生成的代码),但是由于C2280而不能与Visual Studio 2015一起编译,我该如何解决此问题?

我正在考虑以这种方式声明A类:
class A
{
public:
   A(){}
   A(A &&){}
   A(const A&)=default;
};

我错过了什么吗?

最佳答案

在[class.copy]/7中,重点是:



在第18段中,有一个等效的部分用类似的措词来表示副本的分配。

class A
{
public:
   // explicit
   A(){}
   A(A &&){}

   // implicit
   A(const A&) = delete;
   A& operator=(const A&) = delete;
};

这就是为什么您不能复制构造它的原因。如果您提供了一个移动构造函数/赋值,并且您仍然希望该类是可复制的,则必须显式提供这些特殊的成员函数:
    A(const A&) = default;
    A& operator=(const A&) = default;

您还需要声明一个移动分配运算符。如果确实需要这些特殊功能,则可能还需要析构函数。参见Rule of Five

关于c++ - Visual Studio 2013和2015中的C++编译器错误C2280 “attempting to reference a deleted function”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31264984/

10-10 13:56
查看更多