2016-05-15 54 views
0

給定一個參數包和一個字符串向量,我想遞歸地構建一個元組,並且每次都取第一個元組,並將其附加到元組中。所以如果我有一個帶有「string1」,「string2」,「string3」和一個參數包5,2.5,真的向量......結果元組將會是「string1」,5,「string2」,2.5,「string3 「,的確如此。以遞歸方式構建一個元組

繼承人什麼我試過到目前爲止

在我主我做這樣的事情

std::vector<std::string> string_vec; 
std::tuple<> t; 

//initalize string_vec to something 
set_up_strings(string_vec); 

//pass an empty tuple to start building with the strings and args 
tuple_maker(t, string_vec, args...); 

在我的tuple_maker遞歸地把每個之一。

template<typename T, typename... Args, typename... Ts> 
void tuple_maker(std::tuple<Ts...> t, std::vector<std::string> &vec, T value, Args... args) 
{ 
    auto newTup1 = tuple_append(t, vec.begin()); 
    auto newtup2 = tuple_append(newTup1, value); 
    vec.erase(vec.begin()); 

//now pass in the vector and args after removing front of each 
    tuple_maker(newtup2, vec,args...); 
} 

最終當沒有更多的指定參數時,該功能將被調用(結束遞歸)

template<typename... Ts> 
std::tuple<Ts...> tuple_maker(std::tuple<Ts...> t, std::vector<std::string> &vec) 
{ 

int tup_size = std::tuple_size<decltype(t)>::value; 
std::cout<< "final tuple has size of " << tup_size << std::endl; 

//return t; 

} 

如果我通過類似string1-3,和3 ARGS就像我之前提到的,它打印大小爲6的元組,所以我相信它正確地創建了它。但是,我很難將其返回到主函數。我不知道如何設置返回類型,以便它將最終的元組正確地返回到前一個函數,然後返回到main。

參考,助手「tuple_maker」功能,我用的是這裏

template <typename NewType, typename... TupleElem> 
std::tuple<TupleElem..., NewType> tuple_append(const std::tuple<TupleElem...> &tup, const NewType &n) 
{ 
return std::tuple_cat(tup, std::make_tuple(n)); 
} 

我想這樣的事情...

template<typename T, typename... Args, typename... Ts, typename... ret> 
std::tuple<ret...> tuple_maker(std::tuple<Ts...> t, std::vector<std::string> &vec, T value, Args... args) 
+0

如果您使用的是C++ 14,那麼'auto'應該就足夠了......如果不是,您可以嘗試將'auto'與' - > decltype()'結合在一起,在decltype的括號中您應該通過調用生成元組的函數... –

+0

你可以使函數返回類型auto ?,編輯我一直在使用C++ 11,但我會嘗試14 – user2770808

+0

是的,它應該被接受,因爲編譯器可以推導出結果從返回聲明... –

回答

0

您應該從非最終版本的返回值的tuple_maker

return tuple_maker(newtup2, vec, args...); 

而且從最後一個:

return t; 

這樣,各種實例化調用鏈tuple_maker變成了一串尾調用,最後一個返回累計值。

+0

我試過,但我只是不知道該怎麼做。我爲它嘗試了一個可變模板,但那不起作用 – user2770808

+0

「make」是什麼意思?每個特定實例化的返回類型都由編譯器推斷出來,如果你不想枚舉一個元組所構成的所有字符串對,那麼當你想實例化結果對象時,你可以使用關鍵字'auto'。 – bipll

1

我可以看到一對夫婦的可能出現的問題在您的tuple_maker 定義(爲什麼你傳遞一個迭代器tuple_append?),但它 看起來你有什麼你正在嘗試做一個手柄,所以我會讓 你自己排序。

您的問題似乎在問如何確定返回 類型應該爲您的功能。有幾種方法可以做 這個。

其中一個很簡單,但需要大量重複的代碼, 使用使用decltype的尾隨返回類型。但是,由於tuple_maker函數有多行代碼,所以通過其他方法可能更好。

缺席C++ 14(您可以在其中只使用auto作爲返回值), 你可以爲你的函數像這樣創建一個類型的發電機:

#include <tuple> 
#include <type_traits> 
#include <utility> 

template <typename> 
struct RetMaker { 
    using type = std::tuple<>; 
}; 

template <typename T, typename... Rest> 
struct RetMaker<std::tuple<T, Rest...>> { 
    using rest = typename RetMaker<std::tuple<Rest...>>::type; 
    using type = decltype(std::tuple_cat(
           std::declval<std::tuple<std::string, T>>(), 
           std::declval<rest>())); 
}; 

然後你的函數的返回類型爲typename RetMaker<std::tuple<Ts...>>::type

我應該注意到,還有很多其他不同的方法來實現這個目標,包括做不使用std::tuple_cat,但這是第一個彈出到我腦海中的,不需要大量額外打字的方法。 decltype/std::declval位的本質是:給我一個std::string, T元組調用std::tuple_cat產生的類型,並將其遞歸結果應用於元組的其餘部分。