如何将变量作为构造函数参数或函数参数传递
How to pass a variant as constructor parameter or as function argument
我正在阅读有关使用变体实现状态机的信息。我尝试创建一个采用变体参数来初始化状态的构造。但是,当定义构造函数时,我会收到一条警告,指出这被识别为函数声明。
此外,当我尝试为状态定义一个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指出这个问题。
相关文章:
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类