Aart Stuurman Aart Stuurman - 9 days ago 5
C++ Question

Number of function arguments equal to template integer

Say I have a class with an integer template argument. How would I go about adding a function that takes

N
arguments of a given type? If at all possible, I would like to avoid
enable_if
and the likes.

What I currently do is:

template<unsigned int N>
class Foo
{
template <typename To, typename>
using to = To;
public:
template<typename... Args>
void Bar(to<char, Args>... args) // Some arguments of type char
{ /* do stuff */ }
};


This allows for calling Bar:

Foo<3> myfoo;
myfoo.Bar<int, int, int>('a', 'b', 'c');


However, I see two downsides. First, the number of arguments is not necessarily limited to
N
, except by maybe code inside
Bar
.

Second, the user is required to add template parameters to the function. Their values are not actually used, only the number of arguments. This seems unnecessary as we already have this, namely
N
.

Optimal use of the function would look like this:

Foo<3> myfoo;
myfoo.Bar('a', 'b', 'c'); // valid


The following calls generate compile errors.
function does not take this many arguments
, or some similar standard compile error which you would get as if you would define
void(char, char, char)
by hand.

myfoo.Bar('a', 'b');
myfoo.Bar('a', 'b', 'c', 'd'); // error
myfoo.Bar('a', 'b', "flob"); // error
// ...

Answer

If you are using c++14 you could do it like this:

#include <utility>

template<std::size_t N, class = std::make_index_sequence<N>>
class Foo;

template<std::size_t N, std::size_t... Is>
class Foo<N, std::index_sequence<Is...>>{
    void Bar(decltype(Is, char{})... args) // Some arguments of type char
    { /* do stuff */ }
};

[live demo]

For c++11 you would need to implement integer_sequence to make it work... it could be done like this

Comments