尝试引用已删除的函数

尝试引用已删除的函数

本文介绍了错误C2280:尝试引用已删除的函数(atomic< int>)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个class A,其成员变量_atomicVar的类型为std::atomic<int>.

I have a class A with a member variable _atomicVar of type std::atomic<int>.

#include <atomic>

class A
{
public:
    A();
    ~A();

private:
    std::atomic<int> _atomicVar;
};

如果我构建项目,则会出现以下错误:

If I build the project I get the following error:

error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)' : attempting to reference a deleted function

我主要是C#开发人员,所以我还不了解C ++的每个细节.我不知道在哪里使用atomic<int>的副本c.tor.
我也尝试初始化_atomicVar:

I'm mainly a C# developer so I don't know every detail of C++ (yet). I don't know where I use the copy c'tor of atomic<int>.
I also tried to initialize _atomicVar:

std::atomic<int> _atomicVar { 0 };

...但是那没用.
我希望_atomicVar(无需显式初始化)将使用int的默认值进行初始化.
您能告诉我为什么会发生此错误吗?

... but that didn't work.
I would expect that _atomicVar (without an explicit initialization) would get initialized with the default value for int.
Can you tell me why this error occurs?

推荐答案

这是因为的副本构造函数已被删除.

请参见此文档页面.

由于没有为A定义显式的复制构造函数,因此编译器会生成默认的副本构造函数,该默认构造函数只为所有成员调用复制构造函数(std::atomic不允许).

Since you do not define explicit copy constructor for A, compiler generates default one, which simply calls copy constructors for all members (which is not allowed for std::atomic).

解决方案:

class A
{
public:
    A();
    A(const A& origin); // add this line
    ~A();
private:
    std::atomic<int> _atomicVar;
};

A::A(const A& origin)
: _atomicVar(0) //zero-initialize _atomicVar
{
}

编辑

如果您想知道为什么atomic类型不可复制,您可能需要阅读这个问题,尤其是被接受的答案.如果要复制std::atomic的值,可以执行以下操作:

If you wonder, why atomic types are not copyable, you may want to read this question, especially accepted answer. If you want to copy value of std::atomic, you can do it:

A::A(const A& origin)
: _atomicVar(origin._atomicVar.load())
{
}

但是请记住,此操作本身将不是原子操作(对于大多数逻辑而言,这是毫无意义的.)

But keep in mind, that this operation itself will not be an atomic one (and, for most logics, meaningless).

此外,您可能还需要定义显式赋值运算符(请记住三人法则).

Also, you may also want to define explicit assignment operator (remember about Rule of Three).

使程序正常运行的最佳方法是删除以下两种方法:

The best option for proper behaviour of your program would be deleting these two methods:

class A
{
public:
    A();
    A(const A&) = delete;
    ~A();

    A& operator=(const A&) = delete;

private:
    std::atomic<int> _atomicVar;
};

如果您的编译器不支持此功能(例如,VC12之前的任何VC),请将它们声明为私有,并且不提供正文:

If your compiler doesn't support this (e.g. any VC before VC12), declare them as private and do not provide a body:

class A
{
public:
    A();
    ~A();

private:
    //do not define these two
    A(const A&);
    A& operator=(const A&);

private:
    std::atomic<int> _atomicVar;
};

这篇关于错误C2280:尝试引用已删除的函数(atomic&lt; int&gt;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 12:14