Using unique_ptr
is causing some issues within a node tree, producing a hard to find error in memory, Xutility, 2280 errors, citing a call to a deleted function (VS2022/C++20).
The code is a typical node tree, where properties and nodes derive from the same base class attribute collection, properties are polymorphic by data type, and properties are distinct from nodes in that they cannot have child elements of their own.
Adapters are responsible for mapping each node and property type as the parser works through a buffer of char
, adding them to the kids collection on construction.
The tree code is like this (pared back for clarity).
class Base
{
public:
string name; int id; string schemaName; string schemaPath; int suffix;
virtual void makePolymorphic() { };
}
class Prop : public Base
{
public:
int widthInBytes;
virtual string toString() { ... };
}
class IntProp : public Prop
{
public:
int value; int maxValue; int minValue; int default = 0;
string toString() override { return value; }
}
class BoolProp : public Prop
{
bool value; bool default = false;
string toString() override { return value ? "true" : "false"; }
}
// more prop types
class Node : public Base
{
public:
vector<unique_ptr<Base>> kids;
}
class SpecificNode : public Node
{
public:
// final level
}
The compiler complains about a call in std::unique_ptr
to a deleted function, with respect to Base
.
This is an example of the error. It appears when Node
is used as a base for a particular node type with well understood properties and functions:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\memory(3216,5): message : 'std::unique_ptr<Base,std::default_delete<Base>>::unique_ptr(const std::unique_ptr<Base,std::default_delete<Base>> &)': function was explicitly deleted
error C2280: std::unique_ptr<Base,std::default_delete<Base>>::unique_ptr(const std::unique_ptr<Base,std::default_delete<Base>> &)': attempting to reference a deleted function
Since it does not give me a line number to work from, it appears to be a class of errors introduced by using unique_ptr
. I am not sure I understand the error message I am seeing.
If I remove the Base
class, the errors vanish - but the desired polymorphism is also lost.
I suspect I must be missing something in constructor/destructor declarations required to play nice with unique_ptr
, a rule of thumb lore if doing nested nodes. Or is const
-ness related?
If a better collection structure is advised, that would be acceptable in this case.
To answer the request for more information, the full error is as follows:
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\vector(749,1): message : see reference to function template instantiation 'void std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>>::_Construct_n<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>*const &,std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>*const &>(const unsigned __int64,std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> *const &,std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> *const &)' being compiled
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\vector(749,21): message : see reference to function template instantiation 'void std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>>::_Construct_n<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>*const &,std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>*const &>(const unsigned __int64,std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> *const &,std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> *const &)' being compiled
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\vector(745,1): message : while compiling class template member function 'std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>>::vector(const std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>> &)'
1>G:\Dcd.Seq.Data\src\mfChunk.h(427,4): message : see reference to function template instantiation 'std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>>::vector(const std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>> &)' being compiled
1>G:\Dcd.Seq.Data\src\mfChunk.h(426,32): message : see reference to class template instantiation 'std::vector<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>,std::allocator<std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>>>' being compiled
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\xutility(261,49): error C2280: 'std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>::unique_ptr(const std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> &)': attempting to reference a deleted function
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\memory(3216,5): message : see declaration of 'std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>::unique_ptr'
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\memory(3216,5): message : 'std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>::unique_ptr(const std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> &)': function was explicitly deleted
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\xmemory(680,47): error C2280: 'std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>::unique_ptr(const std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> &)': attempting to reference a deleted function
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\memory(3216,5): message : see declaration of 'std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>::unique_ptr'
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include\memory(3216,5): message : 'std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>>::unique_ptr(const std::unique_ptr<Dcd::Seq::Data::M2Base,std::default_delete<Dcd::Seq::Data::M2Base>> &)': function was explicitly deleted
And what is at line 427?
class M2Node : public M2Base
{
public:
vector<unique_ptr<M2Base>> vDef;
};
My original assertion that unique_ptr is the cause. Shared_ptr eliminates this problem.
On account of the time we are mutually spending essentially solving a definition, this is the wrong approach, generically.
My conclusion is that it is way too time consuming to use smart pointers for lists of polymorphic collections, and the time expedient solution is to use well understood pointer semantics - i.e. vector<M2Base*> - until this proves to be a problem, because it very probably won't.
Thanks to all who chimed in.