2016-05-15 11 views
0

パラメータパックと文字列のベクトルが与えられたら、一度に1つずつタプルを再帰的に作成し、それをタプルに追加する必要があります。したがって、 "string1"、 "string2"、 "string3"、および5,2.5、trueのパラメータパックを持つベクトルがあった場合、結果のタプルは "string1"、5、 "string2"、2.5、 "string3 "、本当。私は私のtuple_makerが再帰的にそれぞれの1を追加し、この再帰的にタプルを構築する

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...); 

ような何かが私のメインの中で、これまで

を試みたものを相続人

これ以上引数がない場合、最終的に、この関数が呼び出されます
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...); 
} 

私はstring1-3のようなものを渡す場合

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; 

} 
、および3引数私は前に述べたように(再帰を終了します)、私はそれが正しく作成されていると思うので、それは6のサイズを持つタプルを印刷します。しかし、私は主な機能に戻すのに問題があります。戻り値の型を設定して、最終タプルを前の関数に正しく戻してからメインに戻す方法はわかりません。参照用

は、私が使用するヘルパー「tuple_maker」関数は、ここであなたが非最終版から値を返す必要があり

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

もし 'auto'の結果が十分であれば、' auto'を ' - > decltype()'と組み合わせて実験することができます。ここで、decltypeのかっこでは、タプルを生成する関数の呼び出し... –

+0

あなたは関数の型の自動を返すことができますか?編集私はC++ 11を使ってきましたが、私は試みます14 – user2770808

+0

はいそれはコンパイラが結果を推論することができるように受け入れられるべきです返信文から... –

答えて

0

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

私はこのような何かを試してみました...

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

と最終1から:tuple_maker

return t; 

このように、tuple_makerのさまざまなインスタンス化への呼び出しの連鎖は、累積された値を返す最後の呼び出しの連鎖になります。

+0

私はそれを試みたが、私はそれを作るために何を知っていない。私はそれのためのvariadicテンプレートを試してみましたが、それは動作しませんでした – 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を使用せずにdoを行うなど、これを達成するためのさまざまな方法がありますが、これは大量の追加の入力を必要としない最初のものでした。 decltype/std::declvalビットの本質は次のとおりです。std::tuple_catタプルの呼び出しで発生するタイプを与え、この再帰結果を残りのタプルに適用します。

関連する問題