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;
}
精彩评论