如何将 std::variant 与非平凡的用户对象(稍后构建)一起使用,并让访问者使用自动 lambda?

Posted

技术标签:

【中文标题】如何将 std::variant 与非平凡的用户对象(稍后构建)一起使用,并让访问者使用自动 lambda?【英文标题】:How can I use a std::variant with non-trivial user objects (constructed at a later time), and having the visitor use an auto lambda? 【发布时间】:2020-06-02 22:49:37 【问题描述】:

我有类似这样的代码:

using variant_t = std::variant<MyObj1, MyObj2, MyObj3>;

auto foo()
    variant_t var;

    if (condition1)
        var = MyObj1"A String";
        // Other stuff
     else if (condition2) 
        var = MyObj2123, 12345;
        // Other stuff
     else if (condition3) 
        var = MyObj3SomeObject;
        // Other stuff
     else 
        throw std::runtime_error;
    

    return var;


int main()
    auto var = foo();

    std::visit([&](auto& v)v.call_shared_function_name();, var);

假设所有 MyObj 都是不平凡的,有没有办法让它工作?

我知道 std::monostate 将允许您以这种方式初始化变体并实际上稍后填充它。但是如果我这样做,我就不能在访问者中拥有干净的 auto& lambda,并且必须为每种类型创建一个访问者/lambda。

【问题讨论】:

【参考方案1】:

我知道这可能看起来很傻,或者不那么干净,但您实际上需要使用这些对象之一进行初始化:

variant_t var = MyObj1"A String";

它编译得很好,如果你不能,请告诉我,我会删除答案

【讨论】:

我希望避免这样做,因为实际的对象不像传入字符串那样简单可构造。但是如果没有其他选择,我可能会这样做(幸运的是这部分代码不经常调用) @user9760017 idk.. 可能在具有每次调用时抛出的 call_shared_function_name 的变体列表中添加一个“错误”对象,并使用该对象初始化变体?...跨度> 这实际上不是一个坏主意。如果没有其他标准替代品,也许我会这样做。谢谢! @user9760017 很高兴能提供帮助

以上是关于如何将 std::variant 与非平凡的用户对象(稍后构建)一起使用,并让访问者使用自动 lambda?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 boost::hana::tuple 转换为 std::variant

对 std::variant 中保存的类型调用 << 运算符?

将 std::unique_ptr 的子类与 std::variant 一起使用

我可以将 std::variant<Ts...> 分配给/从 std::variant<Ts..., Ys...> 分配/构造吗?

如何访问`std::variant`的任何孩子的`polymorphic`基类?

使用类作为数据类型时如何在 std::variant 中存储值?