Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++0x: how to get variadic template parameters without reference?

Given the following contrived (and yes, terrible) example:

template<typename... Args>
void something(Args... args)
{
    std::tuple<Args...> tuple; // not initializing for sake of example
    std::get<0>(tuple) = 5;
}

It works if you call it like so:

int x = 10;
something<int>(x);

However, it does not work if you call it like this:

int x = 10;
something<int&>(x);

Because of the assignment to 5. Assuming that I cannot, for whatever reason, initialize the tuple when it is defined, how might I get this to work when specifying the type as a reference?

Specifically, I would like the tuple to be std::tuple<int> even when Args... is int&.

The actual use case for this involves deserializing a string into a tuple where Args... are the parameter types to a function that is then called by unpacking the tuple. It all works great except when the function takes a parameter by reference.

I'm using gcc 4.5.2 but would accept an answer that isn't implemented yet in this compiler.

like image 283
Sydius Avatar asked Dec 04 '22 09:12

Sydius


2 Answers

I don't understand your question. This code works fine with GCC and I see no reason why it shouldn't work.

#include <tuple>

template<typename... Args>
void something(Args... args)
{
  std::tuple<Args...> tuple{args...};
  std::get<0>(tuple) = 5;
}

int main() {
  int x = 10;
  something<int&>(x);
}

[js@HOST2 cpp]$ g++ -std=c++0x main1.cpp
[js@HOST2 cpp]$

I don't know what you mean by "initialize the template".


Since you have now updated the question, I can update my answer

template<typename... Args>
void something(Args... args)
{
  std::tuple<typename std::decay<Args>::type...> tuple;
  std::get<0>(tuple) = 5;
}

decay removes const / volatile, removes references and transforms array and function types to element and function pointers respectively. That is what you seem to look for.

like image 153
Johannes Schaub - litb Avatar answered Dec 11 '22 11:12

Johannes Schaub - litb


Have you tried std::tuple<std::remove_reference<Args>...>?

like image 30
Edward Strange Avatar answered Dec 11 '22 09:12

Edward Strange