2

So I'm trying to get a number of elements in my variadic template like so:

Test(const T& t...);

template<typename T>
inline Class<T>::Test(const T& t...){
     int num = sizeof...(t);
     ...
}

However it doesn't compile and I get the following errors:

error C3523: 'sizeof...' requires as its argument an unexpanded parameter pack

't' is not a valid operand for 'sizeof...'. Did you mean to use 'sizeof'?

What is the correct way to get the number of arguments in t...?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Danich
  • 135
  • 11

2 Answers2

3

Try std::tuple metaprogramming: std::tuple_size<std::tuple<Types...>>::value yields the number of type parameters. For example, this code prints 4:

#include <iostream>
#include <tuple>
#include <cstddef>

template<typename ...Types>
constexpr std::size_t Test(Types&& ... args){
    constexpr std::size_t sz = std::tuple_size<std::tuple<Types...>>::value;
    return sz;
}

int main()
{
    std::size_t val = Test(0, 0L, 'a', std::cin);
    std::cout << val;
}
0

If T were a parameter pack, you could use the following syntax to declare a function that takes a sequence of parameters with types corresponding to those in the parameter pack:

inline Class<T>::Test(const T&... t) { /* ... */ }

However, it appears that T isn't a parameter pack. It's just a single type parameter. Plus, you put the ... in the wrong place. So what you really did was declare a function that takes a single parameter of type T, plus a C-style ellipsis. (Yes, the comma before the ellipsis is optional!)

So when you write sizeof...(t), the compiler complains because t is not a pack. It's just a normal parameter.

Perhaps you wanted to declare Test to be a function that takes an arbitrary number of arguments, but all of type const T&? Unfortunately, there is no easy way to do that in current C++. See Specifying one type for all arguments passed to variadic function or variadic template function w/out using array, vector, structs, etc? for solutions.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312