【问题标题】:Deduce Argument Type For Variadic Template?推断可变参数模板的参数类型?
【发布时间】:2020-09-30 22:42:44
【问题描述】:

有没有办法推断列表的类型以避免传递列表应该是的参数类型,只需从第一个元素类型推断它。

template<typename T, T... Args>
struct Calc
{
    // do stuff with Args
};

// Usage:
Calc<int, 1, 2, 3>::value;

typename<T... Args> Calc { }; // error T undefined

// Desired:
Calc<1, 2, 3>::value;          // auto deduced T = int
Calc<1.0f, 2.0f, 3.0f>::value; // auto deduced T = float

有什么方法可以获得所需的行为,还是我必须将类型作为参数包含在内?

【问题讨论】:

  • 您可以尝试使用 dynamic_cast - 如果您知道可能的类型是什么,那就是。
  • 不,目前还不能进行这种扣除,虽然之前有人提出过:open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3601.html
  • 将值声明为 std::common_type 可能有效吗?
  • 顺便说一句,您不能将 float 作为非类型模板参数。
  • @Jamboree 与问题无关。

标签: c++ templates


【解决方案1】:

这里遵循 Quentin 的建议是一个类的示例,它允许您为任何类型指定非类型可变参数,而无需显式拼写该类型。但是,浮点数不能用作模板非类型参数。

以下编译:

#include <type_traits>

enum class Letters {
        Alpha, Beta, Gamma
};

template<auto... Args>
struct Calc;

template<auto Arg1, auto... Args>
struct Calc<Arg1, Args...> {
        using type = decltype(Arg1);
        static type value;
};

template<>
struct Calc<> {
        using type = void;
};

int main() {
        //Calc<1, 2, 3>::value is int
        static_assert(std::is_same_v<typename Calc<1, 2, 3>::type, int>);

        //Calc<Letters::Alpha, Letters::Gamma>::value is Letters
        static_assert(std::is_same_v<typename Calc<Letters::Alpha, Letters::Gamma>::type, Letters>);

        //Calc<>::value does not exist as the type would be `void`
        static_assert(std::is_same_v<typename Calc<>::type, void>);

        return 0;
}

【讨论】:

    【解决方案2】:

    据我所知,c++14 是不可能的。然而,c++17 引入了用户定义的推导指南,在那里进行了广泛的描述:class template argument deduction

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2015-02-06
    • 1970-01-01
    • 2016-10-05
    • 2019-09-12
    • 2018-07-07
    • 2020-05-11
    相关资源
    最近更新 更多