簡體   English   中英

C++ 編譯器錯誤:使用已刪除的 function std::variant()

[英]C++ compiler error: use of deleted function std::variant()

我不斷收到以下錯誤消息,告訴我我正在使用已刪除的 function,我認為這是 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;
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~

在我的 main.cpp 文件中,我有:

#include <iostream>
#include "Document.hpp"

int main()
{
   DraftState draftState("draft");
   Document<State, Event, TransitionRegister> doc(draftState);
   doc.write("Hello World!");
   doc.read();
   return 0;
}

在我的 Document.hpp 中:

#ifndef DOCUMENT_HPP
#define DOCUMENT_HPP

#include <iostream>
#include <memory>
#include <variant>
#include <optional>
#include "State.hpp"
#include "Event.hpp"

using Event = std::variant<EventWrite, EventRead>;
using State = std::variant<DraftState, PublishState>;

struct TransitionRegister {
   std::optional<State> operator()(DraftState &a_rState, const EventWrite &e) {
      std::cout << a_rState.getState() << std::endl;
      return std::optional<State>(PublishState(e.m_msg));
   }

   std::optional<State> operator()(PublishState &a_rState, const  EventRead &e) {
      std::cout << a_rState.getState() << std::endl;
      std::cout << "Message: " << a_rState.m_msg << std::endl;
      return std::nullopt;
   }
};

template<typename StateVariant, typename EventVariant, typename Transitions>
class Document
{
public:
   Document() {}
   Document(StateVariant &&a_state) {
      m_state = std::move(a_state);
   }
   ~Document() = default;

   void write(std::string writing); // for draft state
   void read();    // for publish state, print out.

   void putText(std::string a_text) { m_text = a_text; }
   std::string getText() { return m_text; }
   void dispatch(const Event &Event);

private:
   std::string m_text;
   StateVariant m_state;
};
#endif // DOCUMENT_HPP

在我的 Document.cpp 中:

#include <iostream>
#include <optional>
#include <variant>
#include "Document.hpp"

template<typename StateVariant, typename EventVariant, typename Transitions>
void Document<StateVariant, EventVariant, Transitions>::dispatch(const Event &Event)
{
   std::optional<State> new_state = std::visit(TransitionRegister{}, m_state, Event);
   if( new_state ) {
      m_state = *std::move( new_state );
   }
}

template<typename StateVariant, typename EventVariant, typename Transitions>
void Document<StateVariant, EventVariant, Transitions>::write(std::string writing) {
    dispatch(EventWrite(writing));
} // for draft state

template<typename StateVariant, typename EventVariant, typename Transitions>
void Document<StateVariant, EventVariant, Transitions>::read() {
   dispatch(EventRead());
} // for publish state, print out.

在我的 State.hpp 中:

#ifndef STATE_HPP
#define STATE_HPP

#include <iostream>

class DraftState {
public:
   DraftState() {}; // 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 = a_state.m_msg; a_state.m_msg = ""; } // move constructor
   DraftState& operator=(DraftState &&a_state) { if(this != &a_state) { m_msg = a_state.m_msg; a_state.m_msg = ""; } return *this; } // move assignable constructor

   ~DraftState() {} // destructor
   std::string getState() { return "DraftState"; }
   std::string m_msg;
};
/*
class ReviewState {

};
*/
class PublishState {
public:
   PublishState() {};
   PublishState(const PublishState &a_state) { m_msg = a_state.m_msg; }
   PublishState(const std::string &a_rMsg) { m_msg = a_rMsg; }
   PublishState(PublishState &&a_state) { m_msg = a_state.m_msg; a_state.m_msg = ""; }
   PublishState& operator=(PublishState &&a_state) { if(this != &a_state) { m_msg = a_state.m_msg; a_state.m_msg = ""; } return *this;}

   ~PublishState() {}
   std::string getState() { return "PublishState"; }
   std::string m_msg;
};
#endif // STATE_HPP

在我的 Event.hpp 中:

#ifndef EVENT_HPP
#define EVENT_HPP

#include <iostream>

class EventWrite {
public:
   EventWrite(const std::string &a_rMsg) { m_msg = a_rMsg; }
   ~EventWrite() { }
   std::string m_msg;
};

class EventRead {
public:
   EventRead() {}
   ~EventRead() {}
};

#endif // EVENT_HPP

我嘗試在自定義構造函數 Document(StateVariant &&a_state) 的初始化列表中添加一個默認構造函數調用,但這似乎也不起作用。 感謝您對理解這條神秘信息的任何幫助。 抱歉,代碼太長了。

雖然您確實需要處理一個最小示例,但核心問題是您的 DraftState 默認構造函數與帶有默認參數的字符串構造函數不明確。 https://godbolt.org/z/hTnsjoWaW

要默認可構造, std::variant要求第一個類型參數是默認可構造的。 歧義導致編譯器認為您的 class 不是默認可構造的,因此也不是變體。

此外,您的 Document 移動構造函數應該使用成員初始值設定項列表,而不是賦值。 而且您的 DraftState 缺少復制賦值運算符,但除非有更多內容,否則我不會明確定義所有復制/移動/析構函數值。 五法則

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM