2011-02-26 85 views
2

鉴于以下做作(是的,可怕的)例子:C++ 0x:如何获取可变参数模板参数而不用引用?

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

它的工作原理,如果你把它像这样:

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

不过,如果你这样调用它不工作:

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

因为分配给5假设我不能,因为种种原因,初始化它定义为当元组,我怎么可能会得到这个工作的时候特异性英作为参考类型?

具体来说,我希望元组为std::tuple<int>,即使当Args...int&

实际的用例涉及到将一个字符串反序列化为一个元组,其中Args...是一个函数的参数类型,然后通过解包该元组来调用该函数。除非函数通过引用获取参数,否则这一切都很好。

我正在使用gcc 4.5.2,但会接受一个尚未在此编译器中实现的答案。

回答

9

我不明白你的问题。这段代码对于GCC工作正常,我没有看到它不应该工作的原因。

#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); 
} 

[[email protected] cpp]$ g++ -std=c++0x main1.cpp 
[[email protected] cpp]$ 

我不知道你是什么意思的“初始化模板”。


既然你现在已经更新的问题,我可以更新我的答案

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

decay删除const/volatile,删除引用,并分别转换阵列和功能类型元素和函数指针。这是你似乎寻找的东西。

+0

对不起,本意是说,“如果我不能初始化元组,”IE不能在你的例子中包含{args ...}。 – Sydius 2011-02-26 07:21:04

+1

@Sydius然后不通过引用类型。您必须初始化一个参考。如果你还没有初始化参考,你会期望'得到<0>(tuple)= 5'吗? – 2011-02-26 07:22:40

+0

我补充说明我的问题。即使模板仅供参考,我也希望元组不会被引用。这个实际使用情况要复杂得多。这只是一个人为的例子来说明问题。 – Sydius 2011-02-26 07:25:10

4

你试过std::tuple<std::remove_reference<Args>...>

+0

我想我可能做错了,但是当我尝试时,我得到:'错误:在'std :: get [with long unsigned int __i = 0ul,_Elements = {std :: (((std ::):: type :: std :: remove_reference &]((std :: remove){typed std :: _ add_ref 元组>&)(&tuple)))= 5'' – Sydius 2011-02-26 07:53:53

+0

当你使用一个元函数时,你必须访问它的返回类型,除非你真的想使用这个元函数作为一个类型本身。我在帖子中忘记了这一点。我认为语法应该是'std :: remove_reference :: type ...' – 2011-02-26 09:03:42