C++ compiler error: use of deleted function std::variant()
C++ compiler error: use of deleted function std::variant()
我不断收到以下错误消息,告诉我我正在使用已删除的函数,我认为这是 std::variant 默认构造函数。
In file included from main.cpp:2:
Document.hpp: In instantiation of ‘Document<StateVariant, EventVariant, Transitions>::Document(StateVariant&&) [with StateVariant = std::variant<DraftState, PublishState>; EventVariant = std::variant<EventWrite, EventRead>; Transitions = TransitionRegister]’:
main.cpp:7:61: required from here
Document.hpp:33:37: error: use of deleted function ‘std::variant<_Types>::variant() [with _Types = {DraftState, PublishState}]’
33 | Document(StateVariant &&a_state) {
| ^
In file included from Document.hpp:6,
from main.cpp:2:
/usr/include/c++/11/variant:1385:7: note: ‘std::variant<_Types>::variant() [with _Types = {DraftState, PublishState}]’ is implicitly deleted because the default definition would be ill-formed:
1385 | variant() = default;
| ^~~~~~~
/usr/include/c++/11/variant:1385:7: error: use of deleted function ‘constexpr std::_Enable_default_constructor<false, _Tag>::_Enable_default_constructor() [with _Tag = std::variant<DraftState, PublishState>]’
In file included from /usr/include/c++/11/variant:38,
from Document.hpp:6,
from main.cpp:2:
/usr/include/c++/11/bits/enable_special_members.h:112:15: note: declared here
112 | constexpr _Enable_default_constructor() noexcept = delete;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
代码大致是:
#include <iostream>
#include <variant>
class DraftState {
public:
DraftState() = default; // default constructor
DraftState(const DraftState &a_state) { m_msg = a_state.m_msg; } // copy constructor
DraftState(const std::string &a_rMsg = "") { m_msg = a_rMsg; } // custom constructor
DraftState(DraftState &&a_state) { m_msg = std::move(a_state.m_msg);} // move constructor
DraftState& operator=(DraftState &&a_state) { if(this != &a_state) { m_msg = std::move(a_state.m_msg); } return *this; } // move assignable constructor
~DraftState() = default; // destructor
std::string getState() { return "DraftState"; }
std::string m_msg;
};
class PublishState{
// similar to DraftState
};
using State = std::variant<DraftState, PublishState>;
template<typename StateVariant>
class Document
{
public:
Document() = default;
Document(StateVariant &&a_state) {
m_state = std::move(a_state);
}
StateVariant m_state;
//...
};
int main()
{
DraftState draftState("draft");
Document<State> doc(draftState);
return 0;
}
我尝试在自定义构造函数 Document(StateVariant &&a_state) 的初始化列表中添加默认构造函数调用,但这似乎也不起作用。感谢任何帮助理解这个神秘消息的人。抱歉代码太长了。
虽然您确实需要处理一个最小示例,但核心问题是您的 DraftState 默认构造函数与带有默认参数的字符串构造函数不明确。参见 https://godbolt.org/z/hTnsjoWaW
要默认可构造,std::variant
要求第一个类型参数是默认可构造的。歧义导致编译器认为您的 class 不是默认可构造的,因此变体也不是。
另外,Document 的移动构造函数应该使用成员初始值设定项列表,而不是赋值。而且您的 DraftState 缺少复制赋值运算符,但除非有更多内容,否则我不会明确定义所有 copy/move/destructor 值。见 Rule of Five.
我不断收到以下错误消息,告诉我我正在使用已删除的函数,我认为这是 std::variant 默认构造函数。
In file included from main.cpp:2:
Document.hpp: In instantiation of ‘Document<StateVariant, EventVariant, Transitions>::Document(StateVariant&&) [with StateVariant = std::variant<DraftState, PublishState>; EventVariant = std::variant<EventWrite, EventRead>; Transitions = TransitionRegister]’:
main.cpp:7:61: required from here
Document.hpp:33:37: error: use of deleted function ‘std::variant<_Types>::variant() [with _Types = {DraftState, PublishState}]’
33 | Document(StateVariant &&a_state) {
| ^
In file included from Document.hpp:6,
from main.cpp:2:
/usr/include/c++/11/variant:1385:7: note: ‘std::variant<_Types>::variant() [with _Types = {DraftState, PublishState}]’ is implicitly deleted because the default definition would be ill-formed:
1385 | variant() = default;
| ^~~~~~~
/usr/include/c++/11/variant:1385:7: error: use of deleted function ‘constexpr std::_Enable_default_constructor<false, _Tag>::_Enable_default_constructor() [with _Tag = std::variant<DraftState, PublishState>]’
In file included from /usr/include/c++/11/variant:38,
from Document.hpp:6,
from main.cpp:2:
/usr/include/c++/11/bits/enable_special_members.h:112:15: note: declared here
112 | constexpr _Enable_default_constructor() noexcept = delete;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
代码大致是:
#include <iostream>
#include <variant>
class DraftState {
public:
DraftState() = default; // default constructor
DraftState(const DraftState &a_state) { m_msg = a_state.m_msg; } // copy constructor
DraftState(const std::string &a_rMsg = "") { m_msg = a_rMsg; } // custom constructor
DraftState(DraftState &&a_state) { m_msg = std::move(a_state.m_msg);} // move constructor
DraftState& operator=(DraftState &&a_state) { if(this != &a_state) { m_msg = std::move(a_state.m_msg); } return *this; } // move assignable constructor
~DraftState() = default; // destructor
std::string getState() { return "DraftState"; }
std::string m_msg;
};
class PublishState{
// similar to DraftState
};
using State = std::variant<DraftState, PublishState>;
template<typename StateVariant>
class Document
{
public:
Document() = default;
Document(StateVariant &&a_state) {
m_state = std::move(a_state);
}
StateVariant m_state;
//...
};
int main()
{
DraftState draftState("draft");
Document<State> doc(draftState);
return 0;
}
我尝试在自定义构造函数 Document(StateVariant &&a_state) 的初始化列表中添加默认构造函数调用,但这似乎也不起作用。感谢任何帮助理解这个神秘消息的人。抱歉代码太长了。
虽然您确实需要处理一个最小示例,但核心问题是您的 DraftState 默认构造函数与带有默认参数的字符串构造函数不明确。参见 https://godbolt.org/z/hTnsjoWaW
要默认可构造,std::variant
要求第一个类型参数是默认可构造的。歧义导致编译器认为您的 class 不是默认可构造的,因此变体也不是。
另外,Document 的移动构造函数应该使用成员初始值设定项列表,而不是赋值。而且您的 DraftState 缺少复制赋值运算符,但除非有更多内容,否则我不会明确定义所有 copy/move/destructor 值。见 Rule of Five.