c++ - 使用 std::get<index> 访问 std::variant

标签 c++ std c++17 variant

如何使用 v.index() 访问变体的成员然后 std::get<index>(v)

当变体具有多个相同类型的条目时很有用。

以下不起作用。此代码无法在 GCC 或 clang 上编译

#include <iostream>
#include <variant>
#include <string>
#include <sstream>

typedef std::variant<int, int, std::string> foo;

std::string bar(const foo f) {

    const std::size_t fi = f.index();
    auto ff = std::get<fi>(f);

    std::ostringstream ss;      
    ss << "Index:" << fi << "   Value: " << ff;
    return ss.str();
}


int main()
{
    foo f( 0 );

    std::cout << bar(f);
}

当然,std::get 有很多版本,所以错误消息很长。

gcc 提示(对于每个版本的 get<>)

prog.cc:10:29: error: the value of 'fi' is not usable in a constant expression
     auto ff = std::get<fi>(f);
                             ^
prog.cc:9:23: note: 'fi' was not initialized with a constant expression
     const std::size_t fi = f.index();
                       ^~
prog.cc:10:29: note: in template argument for type 'long unsigned int'
     auto ff = std::get<fi>(f);

Clang 提示(对于每个版本的 get<>) (re _Tp 或 _Ip 视情况而定)

candidate template ignored: invalid explicitly-specified argument for template parameter '_Tp' 

Wandbox

已更新以询问如何解决而不是错误消息的含义。

最佳答案

std::get<>适用于请求在编译时时已知的变体索引。

如果您需要对其类型在运行时之前未知的变体值进行操作,惯用的方法是使用带有 std::visit 的访问者.

#include <iostream>
#include <variant>
#include <string>

struct output_visitor
{
    template< typename T >
    void operator() ( const T& value ) const
    {
        std::cout << value;
    }   
};

int main()
{
    std::variant<int, std::string> f( 0 );

    std::visit( output_visitor{}, f );
}

这通常可以用 C++14“通用 lambda”来实现

#include <iostream>
#include <variant>
#include <string>

int main()
{
    std::variant<int, std::string> f( 0 );

    std::visit( [](auto v){std::cout << v;} , f );
}

关于c++ - 使用 std::get<index> 访问 std::variant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51624070/

相关文章:

c++ - 生成 boost::hana::set 的常量表达式问题

c++ - '_Unwind_Resume'的多个定义

c++ - Qt——将事件传递给多个对象?

c++ - 移动设备上的 OpenGL vector 图形渲染性能

c++ - 使用 C++ lock_guard 时如何收紧范围?

c++ - printf 与 std::string?

c++ - 用作函数参数时如何定义到类模板工作的转换

c++ - 如何在 Qt Creator 中包含 boost header 库

c++ - 数组中不同类型的对象并获取每个对象的类型

c++ - 将 csv 文件的一行拆分为 std::vector?