其他分享
首页 > 其他分享> > C编译器错误C2280“尝试引用已删除的函数”在Visual Studio 2013和2015中

C编译器错误C2280“尝试引用已删除的函数”在Visual Studio 2013和2015中

作者:互联网

在Visual Studio 2013(版本12.0.31101.00 Update 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附带的编译器会生成复制构造函数并将其标记为= 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开始,强调我的:

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy
constructor is defined as deleted
; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if
the class has a user-declared copy assignment operator or a user-declared destructor.

对于第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,c14,visual-c,copy-constructor
来源: https://codeday.me/bug/20190923/1813474.html