Simple variadic template function can't instantinate

后端 未结 2 1708
夕颜
夕颜 2020-12-19 15:42

I\'m aware that sizeof...(Args...) yields the number of types in a C++0x packed template argument list, but I wanted to implement it in terms of other features

相关标签:
2条回答
  • 2020-12-19 16:03

    You didn’t declare a base case. You have a template-free overload of your num_args function but when calling a function num_args<T...>() this will never be found, for obvious reasons: it will always try to instantiate a function template.

    You can however specialise your function template to perform the desired operation.

    template <>
    constexpr size_t num_args<>()
    {
        return 0;
    }
    

    However, this won’t work either since here you’re specialising a parameterless function template and such a template doesn’t exist: your other function template num_args always has at least one argument, H.

    In order to really make this work you need partial specialisations, and these only exist for class templates. So this is what you need here.

    template <typename T>
    struct num_args_t;
    
    template <>
    struct num_args_t {
        static size_t const value = 0;
    };
    
    template <typename H, typename T...>
    struct num_args_t {
        static size_t const value = num_args_t<T...>::value + 1;
    };
    
    template <typename T...>
    constexpr size_t num_args() {
        return num_args_t<T...>::value;
    }
    
    0 讨论(0)
  • 2020-12-19 16:03

    Konrad's answer should get you going, but I think the more idiomatic way such things are usually expressed is with static member constants, so I just wanted to present that solution:

    #include <type_traits>
    
    template <typename...> struct arg_size;  // no primary definition needed
    
    template <typename T, typename ...Args> struct arg_size<T, Args...>
      : public std::integral_constant<std::size_t, 1 + arg_size<Args...>::value> { };
    
    template <> struct arg_size<>
      : public std::integral_constant<std::size_t, 0> { };
    

    Then you get your argument pack size via arg_size<Args...>::value.

    0 讨论(0)
提交回复
热议问题