如何将变量作为构造函数参数或函数参数传递

How to pass a variant as constructor parameter or as function argument

本文关键字:参数 函数 参数传递 构造函数 变量      更新时间:2023-10-16

我正在阅读有关使用变体实现状态机的信息。我尝试创建一个采用变体参数来初始化状态的构造。但是,当定义构造函数时,我会收到一条警告,指出这被识别为函数声明。

此外,当我尝试为状态定义一个setter时,当尝试调用它时会产生编译器错误

这是代码

#include "pch.h"
#include <iostream>
#include <variant>
#include <cassert>
struct DoorState
{
    struct DoorOpened {};
    struct DoorClosed {};
    struct DoorLocked {};
    using State = std::variant<DoorOpened, DoorClosed, DoorLocked>;
    DoorState()
    {
    }
    DoorState(State & state)
    {
        m_state = state;
    }
    void open()
    {
        m_state = std::visit(OpenEvent{}, m_state);
    }
    void close()
    {
        m_state = std::visit(CloseEvent{}, m_state);
    }
    void lock()
    {
        m_state = std::visit(LockEvent{}, m_state);
    }
    void unlock()
    {
        m_state = std::visit(UnlockEvent{}, m_state);
    }
    struct OpenEvent
    {
        State operator()(const DoorOpened&) { return DoorOpened(); }
        State operator()(const DoorClosed&) { return DoorOpened(); }
        // cannot open locked doors
        State operator()(const DoorLocked&) { return DoorLocked(); }
    };
    struct CloseEvent
    {
        State operator()(const DoorOpened&) { return DoorClosed(); }
        State operator()(const DoorClosed&) { return DoorClosed(); }
        State operator()(const DoorLocked&) { return DoorLocked(); }
    };
    struct LockEvent
    {
        // cannot lock opened doors
        State operator()(const DoorOpened&) 
        { 
            std::cout << "DoorOpened" << std::endl;
            return DoorOpened(); 
        }
        State operator()(const DoorClosed&) { return DoorLocked(); }
        State operator()(const DoorLocked&) { return DoorLocked(); }
    };
    struct UnlockEvent
    {
        // cannot unlock opened doors
        State operator()(const DoorOpened&) { return DoorOpened(); }
        State operator()(const DoorClosed&) { return DoorClosed(); }
        // unlock
        State operator()(const DoorLocked&) { return DoorClosed(); }
    };
    void set(State state)
    {
    }
    State m_state;
};
int main()
{
    //DoorState s(DoorState::DoorOpened);
    DoorState s; 
    s.set(DoorState::DoorOpened);
    s.lock();
    return 0;
}

in

s.set(DoorState::DoorOpened);

你正在传递一个类型,你应该传递一个类型的实例,尝试

s.set(DoorState::DoorOpened{});

在此更改之后,我能够在MSVC 2019(16.1.3(中进行编译

编辑

:这是解决 Scheff 和 Jarod24 注释的编辑,如果我们要取消注释构造函数并写入,就会出现最令人烦恼的解析情况

DoorState s(DoorState::DoorOpened());

这本可以使用统一初始化语法修复,例如https://arne-mertz.de/2015/07/new-c-features-uniform-initialization-and-initializer_list/

DoorState s{DoorState::DoorOpened{}};

这将解决最棘手的解析问题,但会产生一个新问题:DoorState::DoorOpened{}本来是临时的,它永远不会绑定到 ctor 的输入参数:

DoorState(State& state)

然后我们需要将其更改为

DoorState(const State& state)

再次感谢Jarod和Scheff指出这个问题。