如何从 std:::tuple 获取可变参数来解压另一个 std::tuple?

问题描述 投票:0回答:1

我正在尝试将模板参数列表(枚举类,而不是类型名称)转换为 std::tuple 模板参数的相应类型名称。我猜如果我能以某种方式将可变参数列表命名为

using type = ...
,我也许可以在下一个模板递归中扩展它

所以,我有枚举类:

enum class object_t{
    STR,
    INT,
    FLOAT,
};

模板应该提供具体的类(一些 std::tuple):

template <object_t _obj, object_t ...Args>
struct concrete {
        // here's the part I need to correct
    using type = std::tuple<typename concrete<_obj>::type, typename concrete<Args...>::type>;
};

减少递归的专业化:

template <>
struct concrete<object_t::STR> {
    using type = std::string;
};

template <>
struct concrete<object_t::INT> {
    using type = int64_t;
};

template <>
struct concrete<object_t::FLOAT> {
    using type = double;
};

以及 ::type 简写的 using 声明

template<object_t _obj, object_t ...Args>
using concrete_t = typename concrete<_obj, Args...>::type;

最终,我想要类似的东西

concrete_t<object_t::INT, object_t::FLOAT, object_t::STR>

相当于

std::tuple<int64_t, double, std::string>

目前,应该会产生如下结果:

std::tuple<int64_t, std::tuple<double, std::string>>

相反。

我不是最擅长可变参数模板,但我在想如果(通用模板的)使用类型是参数包而不是元组,我也许可以为下一个元组(其参数列表)解压它然后我将不得不再次获取等等)。 比如:

template <object_t _obj, object_t ...Args>
struct concrete {
    using type = std::tuple<typename concrete<_obj>::type, typename concrete<Args...>::type...>::elements_type;
};

其中 elements_type 是一个可变参数包,而 ::type... 将其解包

但即使这样似乎也不正确,因为 root::type 将是一个参数包,而不是所需的 std::tuple。也许需要另一个模板,我不知道。

任何建议都可能会有很大帮助,谢谢!

c++ templates variadic-templates specialization stdtuple
1个回答
0
投票

如果有人需要这个,解决方案,感谢@IgorTandetnik,看起来像这样:

enum class object_t{
    STR,
    INT,
    FLOAT,
};

template<object_t ...Args>
struct concrete_traits;

template<>
struct concrete_traits<object_t::STR> {
    using type = std::string;
};

template<>
struct concrete_traits<object_t::INT> {
    using type = int64_t;
};

template<>
struct concrete_traits<object_t::FLOAT> {
    using type = double;
};

template <object_t ...Args> struct concrete {
    using type = std::tuple<typename concrete_traits<Args>::type...>;
};

template<object_t ...Args>
using concrete_t = typename concrete<Args...>::type;

这个答案基于@IgorTandetnik 评论。

为了消除单个模板参数的简单情况下的 std::tuple,特化

template<object_t _obj>
struct concrete<_obj> {
    using type = typename concrete_traits<_obj>::type;
};
例如,

使

concrete_t<object_t::STR>
成为
std::string
而不是
std::tuple<std::string>

© www.soinside.com 2019 - 2024. All rights reserved.