Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the syntax for variadic template array reference parameters?

I don't know if what I have is a compiler bug or if I just don't know the syntax for what I'm trying to do. Imagine a function that takes 2 array references:

void takeArrays(const char (&str1)[4], const char (&str2)[4]) {
}

This compiles fine when called with:

takeArrays("foo", "bar");

Why would I want to do this? Because passing const char* loses the size information of the string literal, and that's important for what I'm doing.

What I really want to do, however, is pass a variadic number of array references. This is where things get slightly ugly (it gets worse). I naively tried this:

template<typename... Args>
void takeArrays(const char (&Args... strs)[4]) {
}

And got "error: variable or field ‘takeArrays’ declared void" and "error: expected primary-expression before ‘const’" (gcc 4.6). So I tried this:

template<typename... Args>
void takeArrays(const char (&(Args... strs))[4]) {
}

And got "no matching function for call to ‘takeArrays(const char [4], const char [4])’" and "candidate is template<class ... Args> void takeArrays(const char (& (*)(Args ...))[4])". Which is unreadable but seems close to what I want. I've tried many variations and can't seem to get it to compile.

Assuming there's a proper way to write the above, what I really want to do is call:

takeArrays("foo", "foobar", "longerstring");

And get a variadic list of arrays of different sizes, i.e. the call above should be expanded by the compiler to:

void takeArrays(const char (&str1)[4], const char (&str2)[7],
                const char (&str3)[13]);

Which was the first think I tried doing, and my attempt was something like:

template<size_t... Sizes>
void takeArrays(const char (&strs)[Sizes]...);

Needless to say all I got was error messages. I'm aware that what I'm trying to do is a bit crazy but I really want to know if it's possible, and if so, what the appropriate syntax is. Thanks in advance.

like image 583
Átila Neves Avatar asked Nov 06 '12 17:11

Átila Neves


People also ask

What is Variadic template in C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.

What is the use of Variadic templates?

With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.

What is non type template parameters?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.

How do you use template arguments in C++?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)


1 Answers

The syntax for variadic arrays of the same element type is:

template<size_t... Sizes>
void takeArrays(const char (&...args)[Sizes]);

This is similar to the general variadic const reference syntax:

template<typename... Args>
void takeArrays(const Args &...args);

An easy way to remember is that the ellipsis goes immediately before the parameter name.

like image 159
ecatmur Avatar answered Sep 20 '22 16:09

ecatmur