简体   繁体   中英

Deduce Argument Type For Variadic Template?

Is there a way to deduce the type of a list as to avoid having to pass the type of argument the list should be, just deduce it from the first element type.

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

Is there any way to get the desired behavior or do i have to include the type as a parameter?

Following the Quentin's suggestion here is an example of a class that allows you to specify the non-type varargs for any type, without spelling the type explicitly. However, floats cannot be used as template non-type arguments.

The following compiles:

#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;
}

As far as I know it is not possible up to c++14. However c++17 introduces User-defined deduction guides described extensively there: class template argument deduction

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM