Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic templates with 'const' parameter overloading

Reduced sample code:

#include <iostream>

template<typename T>
void func(T &x)
{
    std::cout << "non-const " << x << std::endl;
}

template<typename T>
void func(const T &x)
{
    std::cout << "const " << x << std::endl;
}

template<typename ...ARGS>
void proxy(ARGS ...args)
{
    func(args...);
}

int main()
{
    int i = 3;

    func(i);
    func(5);
    func("blah");

    proxy(i);
    proxy(5);
    proxy("blah");
}

Expected output:

non-const 3
const 5
const blah
non-const 3
const 5
const blah

Actual output:

non-const 3
const 5
const blah
non-const 3
non-const 5
non-const blah

So somehow the const qualifier of the function parameter gets lost when put through the variadic template. Why? How can I prevent this?

PS: tested with GCC 4.5.1 and SUSE 11.4

like image 843
user1346466 Avatar asked Apr 20 '12 12:04

user1346466


People also ask

What are Variadic templates 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. However, variadic templates help to overcome this issue.

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 a variadic function in C?

Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.

What is parameter pack in c++?

Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.


1 Answers

You just stumble upon the forwarding problem. This issue is solved using perfect forwarding.

Basically, you need to take your parameters by rvalue-reference, and rely on std::forward to correctly forward them while keeping their nature:

template<typename ...Args>
void proxy(Args&& ...args)  
{
    func(std::forward<Args>(args)...);
}
like image 171
Luc Touraille Avatar answered Sep 24 '22 01:09

Luc Touraille