【问题标题】:Use of emplace function of std::variant in template [duplicate]在模板中使用 std::variant 的 emplace 函数
【发布时间】:2020-07-09 15:10:32
【问题描述】:

我正在尝试使用有限状态机和 std::variant<..>

std::variant 将保存所有可能的状态。状态将在 State 类中定义。

我希望将 std::monostate 作为第一种类型的 State 变体,以将其用作“不更改状态”值。 所以定义是:第一种是std::monostate,第二种是fsm的初始状态。

由于 std::variant 被初始化为它的第一个元素,我想在构造函数中使用 emplace。

template <typename StateVariant>
class fsm
{
public:
    StateVariant state;
    fsm()
    {
        state.emplace<1>();
    };
};

struct Initial{};
struct Running{};

using State = std::variant<std::monostate,Initial,Running>;

fsm<State> myFSM;

但这会产生编译时错误:

..\fsm_emplace.cpp: In constructor 'fsm<StateVariant>::fsm()':
..\fsm_emplace.cpp:15:20: error: expected primary-expression before ')' token
   15 |   state.emplace<1>();};

但是,当我在非模板代码中使用相同的构造时:

State myState;

void setup()
{
    myState.emplace<1>();
}

emplace函数有使用限制吗?

【问题讨论】:

标签: c++ templates c++17 emplace std-variant


【解决方案1】:

由于状态取决于模板名称,因此您必须添加template

state.template emplace<1>();

【讨论】:

    【解决方案2】:

    emplace函数有使用限制吗?

    我不知道正式规则的措辞,但您需要在这里使用template 关键字。 clang 给出了一个更具描述性的错误“在依赖模板名称 'emplace' 之前缺少 'template' 关键字”。将 state.emplace&lt;1&gt;(); 更改为 state.template emplace&lt;1&gt;(); 将修复构建错误。

    尽管对于它的价值,我也会考虑在成员初始化程序中使用in_place_index_t(由 Nicol Bolas 在 cmets 中建议)是一个更优雅的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多