Visual Studio C++引用删除函数编译错误

Visual Studio C++ reference deleted function compile error

如果我尝试编译这个 (Visual Studio 2015):

#define EXPORT_API __declspec(dllexport)

//#include "readerwriterqueue.h"
#include <map>
#include <thread>

class BaseClass
{
public:
    class A {
        std::thread thd;
        //moodycamel::BlockingReaderWriterQueue<int> processqueue;
    };

    std::map<unsigned int, A> mpmap;
};  // End class BaseClass

class EXPORT_API B : public BaseClass { };

我收到关于

的错误消息
Severity    Code    Description Project File    Line    Suppression State
Error   C2280   'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)': attempting to reference a deleted function    Example C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0 737 

控制台输出:

    Build started...
1>------ Build started: Project: Example, Configuration: Debug x64 ------
1>Example.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(737): error C2280: 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)': attempting to reference a deleted function
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility(112): note: see declaration of 'std::pair<const _Kty,_Ty>::pair'
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(857): note: see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,_Ty&>(_Objty *,_Ty &)' being compiled
1>        with
1>        [
1>            _Other=std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>,
1>            _Objty=std::pair<const unsigned int,BaseClass::A>,
1>            _Ty=std::pair<const unsigned int,BaseClass::A>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(857): note: see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,_Ty&>(_Objty *,_Ty &)' being compiled
1>        with
1>        [
1>            _Other=std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>,
1>            _Objty=std::pair<const unsigned int,BaseClass::A>,
1>            _Ty=std::pair<const unsigned int,BaseClass::A>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(996): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,_Ty&>(std::allocator<_Other> &,_Objty *,_Ty &)' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>>,
1>            _Ty=std::pair<const unsigned int,BaseClass::A>,
1>            _Other=std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>,
1>            _Objty=std::pair<const unsigned int,BaseClass::A>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(995): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,_Ty&>(std::allocator<_Other> &,_Objty *,_Ty &)' being compiled
1>        with
1>        [
1>            _Alloc=std::allocator<std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>>,
1>            _Ty=std::pair<const unsigned int,BaseClass::A>,
1>            _Other=std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>,
1>            _Objty=std::pair<const unsigned int,BaseClass::A>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(889): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,_Ty&>(_Ty *,_Ty &)' being compiled
1>        with
1>        [
1>            _Other=std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>,
1>            _Ty=std::pair<const unsigned int,BaseClass::A>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(887): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,_Ty&>(_Ty *,_Ty &)' being compiled
1>        with
1>        [
1>            _Other=std::_Tree_node<std::pair<const unsigned int,BaseClass::A>,void *>,
1>            _Ty=std::pair<const unsigned int,BaseClass::A>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1939): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_comp_alloc<_Traits>::_Buynode<std::pair<const _Kty,_Ty>&>(std::pair<const _Kty,_Ty> &)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Traits=std::_Tmap_traits<unsigned int,BaseClass::A,std::less<unsigned int>,std::allocator<std::pair<const unsigned int,BaseClass::A>>,false>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1939): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_comp_alloc<_Traits>::_Buynode<std::pair<const _Kty,_Ty>&>(std::pair<const _Kty,_Ty> &)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Traits=std::_Tmap_traits<unsigned int,BaseClass::A,std::less<unsigned int>,std::allocator<std::pair<const unsigned int,BaseClass::A>>,false>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1966): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_or_move<std::pair<const _Kty,_Ty>,std::integral_constant<bool,false>>(std::pair<const _Kty,_Ty> &,std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag,_Is_set)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>,
1>            _Is_set=std::integral_constant<bool,false>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1965): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_or_move<std::pair<const _Kty,_Ty>,std::integral_constant<bool,false>>(std::pair<const _Kty,_Ty> &,std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag,_Is_set)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>,
1>            _Is_set=std::integral_constant<bool,false>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1921): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_nodes<_Moveit>(std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *,std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *,_Moveit)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>,
1>            _Moveit=std::_Tree<std::_Tmap_traits<unsigned int,BaseClass::A,std::less<unsigned int>,std::allocator<std::pair<const unsigned int,BaseClass::A>>,false>>::_Copy_tag
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1921): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_nodes<_Moveit>(std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *,std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *,_Moveit)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>,
1>            _Moveit=std::_Tree<std::_Tmap_traits<unsigned int,BaseClass::A,std::less<unsigned int>,std::allocator<std::pair<const unsigned int,BaseClass::A>>,false>>::_Copy_tag
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1104): note: see reference to function template instantiation 'void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy<std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag>(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &,_Moveit)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>,
1>            _Moveit=std::_Tree<std::_Tmap_traits<unsigned int,BaseClass::A,std::less<unsigned int>,std::allocator<std::pair<const unsigned int,BaseClass::A>>,false>>::_Copy_tag
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1104): note: see reference to function template instantiation 'void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy<std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag>(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &,_Moveit)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>,
1>            _Moveit=std::_Tree<std::_Tmap_traits<unsigned int,BaseClass::A,std::less<unsigned int>,std::allocator<std::pair<const unsigned int,BaseClass::A>>,false>>::_Copy_tag
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree(1095): note: while compiling class template member function 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::operator =(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &)'
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\map(154): note: see reference to function template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::operator =(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &)' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\map(73): note: see reference to class template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A,
1>            _Pr=std::less<unsigned int>,
1>            _Alloc=std::allocator<std::pair<const unsigned int,BaseClass::A>>
1>        ]
1>..\..\Example.cpp(15): note: see reference to class template instantiation 'std::map<unsigned int,BaseClass::A,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' being compiled
1>        with
1>        [
1>            _Kty=unsigned int,
1>            _Ty=BaseClass::A
1>        ]
1>Done building project "Example.vcxproj" -- FAILED.
StopOnFirstBuildError: Build cancelled because project "Example" failed to build.
Build has been canceled.

但是,如果我删除“EXPORT_API”声明,错误就会消失。或者如果我删除地图,错误就会消失。我以线程为例在不涉及第 3 方 API 的情况下重新创建问题,但我真的想使用此处找到的注释掉的第 3 方 API:https://github.com/cameron314/readerwriterqueue。它产生相同的错误。我最终需要将 API 导出到 DLL,但我将问题缩小到这段更小的代码。有人看到这个问题吗?

std::thread对象不是可复制对象,复制构造函数被删除:

thread( const thread& ) = delete; (since C++11)

This作为classA的成员,使得classA对象也不可复制,删除A的复制构造函数。最后,它使std::pair不可复制,删除它的复制构造函数,作为错误报告。 因此 A 不能是地图中的值。 EXPORT_API无所谓。

您可以在 A.

中使用指向 std::thread 的原始指针或共享指针