【问题标题】:C++ Get std::typeindex of type currently help by std::variantC++获取std::variant当前帮助的类型的std::typeindex
【发布时间】:2019-11-15 17:18:57
【问题描述】:

如何通过 c++ 中的变体获取当前帮助类型的 std::typeindex

假设我有一个变体:

using variant_t = std::variant<int, float, bool, double, std::string>;

我希望能够创建函数:

std::typeindex get_held_type(const variant_t& var);

这只是出于好奇,我知道这不是处理变体中数据的常用方法。

如果我将另一个类型添加到variant_t,我不想更改任何其他代码。即,类型需要自我注册。

到目前为止,这是我的尝试。我有点作弊,因为我使用映射而不是函数,并且必须构造一个对象才能在运行时注册类型。

#include <iostream>
#include <variant>
#include <string>
#include <vector>
#include <typeindex>
#include <map>

using variant_t = std::variant<int, float, bool, double, std::string>;
static constexpr size_t variant_t_size = std::variant_size<variant_t>();
static auto get_held_type = std::map<size_t, std::type_index>{};

//loop across all types in the variant
template<size_t N>
struct crtp : crtp<N - 1>{
    //ctor
    crtp(){
        get_held_type[N] = std::type_index(typeid (std::get<N>(variant_t{})));
    }
};

template<>
struct crtp<0>{
    //ctor
    crtp(){
        get_held_type[0] = std::type_index(typeid (std::get<0>(variant_t{})));
    }
};

static crtp<variant_t_size-1> registerTypes;

int main()
{
    variant_t var = 3.141;
    std::cout << get_held_type[var.index()].name() << std::endl;

}

但是由于编译器错误,gcc 失败:

/usr/include/c++/9/tuple:1674: error: no matching function for call to ‘std::type_index::type_index()’
 1674 |         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
      |                                                                      ^

【问题讨论】:

  • std::variant::index 返回从零开始的位置索引,即如果variant&lt;int,float,bool&gt; 类型的变体持有布尔值,则索引将为 2。我需要类型索引,其中包含保证在整个应用程序中保持一致的类型的哈希码,以及基于编译器的类型名称。
  • 我想我明白了。你想要更多这样的东西:en.cppreference.com/w/cpp/utility/variant/variant_alternative
  • 这看起来很有希望。我不再使用计算机,所以我无法尝试。你认为这可以用来创建我的“get_held_type”函数吗?
  • 我认为这是正确的方向。但是您可能会对这个 SO 问题的答案更感兴趣:stackoverflow.com/questions/53696720/…

标签: c++ reflection variant crtp algebraic-data-types


【解决方案1】:

std::visit 在以统一的方式处理所有备选方案时非常方便。

std::visit([](auto& v) -> std::type_index { return typeid(v); }, var)

完整演示:

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

using variant_t = std::variant<int, float, bool, double, std::string>;

int main() {
    variant_t var = 3.141;
    std::cout << std::visit([](auto& v) -> std::type_index { return typeid(v); }, var).name() << '\n';
}

【讨论】:

  • 您可以在带有 std::visit 的 lambda 中使用 auto!?很酷。谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 2021-09-20
  • 2020-01-02
  • 2019-10-11
相关资源
最近更新 更多