为可变参数模板推断参数类型?

时间:2014-09-18 21:12:32

标签: c++ templates

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

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

有没有办法获得所需的行为,还是我必须将类型作为参数包含在内?

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

据我所知,不可能达到c ++ 14。但是,c ++ 17引入了广泛描述的用户定义的演绎指南class template argument deduction