2012-04-04 48 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