开发者

Variadic functions (without arguments!)

开发者 https://www.devze.com 2023-02-13 11:27 出处:网络
Let\'s assume you want to do this in C++0x: size_t count_int() { return 0; } template<typename T, typename... Tn>

Let's assume you want to do this in C++0x:

size_t count_int() { return 0; }
template<typename T, typename... Tn>
size_t count_int(T a0, Tn... an) {
    size_t n = is_integer<T开发者_StackOverflow>::value ? 1 : 0;
    return n + count_int(an...);
}

Nice, but it feels unnecessary to pass around the arguments. Unfortunately, this does not work:

size_t count_int() { return 0; }
template<typename T, typename... Tn>
size_t count_int() {
    size_t n = is_integer<T>::value ? 1 : 0;
    return n + count_int<Tn...>();
}

GCC complains error: no matching function for call to 'count_int()' in the next-to-last line. Why and how can this be fixed? Thanks.


This works:

template <typename T>
size_t count_int()
{
   return is_integer<T>::value ? 1 : 0;
}

template<typename T, typename T1, typename... Tn>
size_t count_int() {
    size_t n = is_integer<T>::value ? 1 : 0;
    return n + count_int<T1,Tn...>();
};


It fails because you have no base case for when the parameter pack contains no values- as the count_int() base case you used earlier isn't templated and thus cannot be called with <Tn...>, even when Tn is empty. That is why it fails. As to how it can be fixed, I have little idea.


This is because the stopping condition is not a function template so when you call count_int<Tn...>(); with an empty Tn the non-templated function isn't found.

If you try to change the stopping condition to a template:

template <typename...>
size_t count_int() { return 0; }

You'll get an error since it's ambiguous which function you're calling when you do have parameters in the parameter pack.

You can solve this by forwarding the call the a template class and avoid the recursion altogether. Something like the following should work (although I haven't succeeded to do so yet)

template <typename T, typename... Tn>
struct int_counter {
    enum { value = is_integer<T>::value + int_counter<Tn...>::value; }
};

template <>
struct int_counter<> {
    enum { value = 0; }
};

template <typename... Tn>
size_t count_int() { 
    return int_counter<Tn>::value;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消