2012-04-04 45 views
4

因此,我有一些在C++ 11之前编写的基于模板参数解析字符串的代码。我希望使用可变参数模板,而不是为每个参数数量定义一个定义,但我无法正确地初始化一个元组。见我想这是什么简单的代码,这是2个参数的特殊情况:使用可变参数模板构建元组

template <typename Arg1, typename Arg2> 
struct parser 
{ 
    static tuple<Arg1, Arg2> parse(const string& str) 
    { 
    Arg1 arg1; 
    Arg2 arg2; 
    // do the parsing with for example stringstream 
    return tuple<Arg1, Arg2>(arg1, arg2);    
    } 
}; 

我在与把参数元组的可变参数的情况下的问题。我可以构造返回值持有者:

tuple<Args...> retVal; 

但我不知道是否有方法遍历参数并将它们放入一个元组中。我已经看到了一些递归魔术来获得例如printf函数,但我不知道它是否可以应用于这种情况。

+0

你试图改变根据您的元组的类型什么来自字符串解析? – cababunga 2012-04-04 16:05:32

+1

可以在不使用递归的情况下查看元组的所有元素,但需要额外的函数调用。我已经多次描述过该技术([here](http://stackoverflow.com/questions/9730593/how-can-i-call-a-set-of-variadic-base-class-constructors-based-on 9731981#9731981),[这里](http://stackoverflow.com/questions/7381805/c-c11-switch-statement-for-variadic-templates/7383493#7383493)和[这里]( http://stackoverflow.com/questions/7089284/dynamic-dispatching-of-template-functions/7089649#7089649))。 (在每种情况下,重要的位都是“索引”。) – 2012-04-04 16:27:33

回答

15

你不需要辅助类。用功能来代替它。

template <typename T> std::tuple<T> parse(std::istream& is) 
{ 
    T t; is >> t; 
    return std::tuple<T>(std::move(t)); 
} 

template <typename T, typename Arg, typename... Args> 
std::tuple<T, Arg, Args...> parse(std::istream& is) 
{ 
    T t; is >> t; 
    return std::tuple_cat(std::tuple<T>(std::move(t)), 
         parse<Arg, Args...>(is)); 
} 

template <typename... Args> 
std::tuple<Args...> parse(const std::string& str) 
{ 
    std::istringstream is(str); 
    return parse<Args...>(is); 
} 

编辑:今天,我的想法是如何通过使用扩展到做一个非常简单的方法:

template <typename T> T read(std::istream& is) 
{ 
    T t; is >> t; return t; 
} 

template <typename... Args> 
std::tuple<Args...> parse(std::istream& is) 
{ 
    return std::make_tuple(read<Args>(is)...); 
} 

template <typename... Args> 
std::tuple<Args...> parse(const std::string& str) 
{ 
    std::istringstream is(str); 
    return parse<Args...>(is); 
} 
+0

thanx,我不知道有tuple_cat这样的函数,太棒了! – Rolle 2012-04-04 19:27:21

+0

@ipc如果您使用std :: make_tuple(请参阅(is)...),似乎流的读取顺序未定义。请参见http://stackoverflow.com/questions/14056000/how-to-avoid-undefined-execution-order-for-the-constructors-when-using-stdmake – 2012-12-30 08:49:35

+1

@ErikSjölund:AFAIR它有明确的定义(见§8.5。 4/4)。 – ipc 2013-01-02 13:14:49