これは、c++11 機能を使用して実際に実行可能です。
はい、initializer_list は、そのすべての要素が同じ型であることを望んでいます。static_cast
秘訣は、必要なすべての型に対応できるラッパー クラスを作成できることです。これは簡単に実現できます。
template <typename... tlist>
class MultiTypeWrapper {
};
template <typename H>
class MultiTypeWrapper<H> {
public:
MultiTypeWrapper() {}
MultiTypeWrapper(const H &value) : value_(value) {}
operator H () const {
return value_;
}
private:
H value_;
};
template <typename H, typename... T>
class MultiTypeWrapper<H, T...>
: public MultiTypeWrapper<T...> {
public:
MultiTypeWrapper() {}
MultiTypeWrapper(const H &value) : value_(value) {}
// If the current constructor does not match the type, pass to its ancestor.
template <typename C>
MultiTypeWrapper(const C &value) : MultiTypeWrapper<T...>(value) {}
operator H () const {
return value_;
}
private:
H value_;
};
暗黙的な変換コンストラクターを使用すると、{1,2.5,'c',4} のようなものを MultiTypeWrapper 型の initializer_list (または、initializer_list を暗黙的に変換するベクトル) に渡すことができます。これは、次のようなintializer_listを引数として受け入れる関数を記述できないことを意味します。
template <typename... T>
std::tuple<T...> create_tuple(std::vector<unit_test::MultiTypeWrapper<T...> > init) {
....
}
別のトリックを使用して、ベクトル内の各値を元の型にキャストし ( の定義で暗黙的な変換を提供していることに注意してくださいMultiTypeWrapper
)、それをタプル内の対応するスロットに割り当てます。テンプレート引数の再帰のようなものです:
template <int ind, typename... T>
class helper {
public:
static void set_tuple(std::tuple<T...> &t, const std::vector<MultiTypeWrapper<T...> >& v) {
std::get<ind>(t) = static_cast<typename std::tuple_element<ind,std::tuple<T...> >::type>(v[ind]);
helper<(ind-1),T...>::set_tuple(t,v);
}
};
template <typename... T>
class helper<0, T...> {
public:
static void set_tuple(std::tuple<T...> &t, const std::vector<MultiTypeWrapper<T...> >& v) {
std::get<0>(t) = static_cast<typename std::tuple_element<0,std::tuple<T...> >::type>(v[0]);
}
};
template <typename... T>
std::tuple<T...> create_tuple(std::vector<unit_test::MultiTypeWrapper<T...> > init) {
std::tuple<T...> res;
helper<sizeof...(T)-1, T...>::set_tuple(res, init);
return res;
}
set_tuple
C++ は関数の特殊化をサポートしていないため、ヘルパー クラスを作成する必要があることに注意してください。コードをテストしたい場合:
auto t = create_tuple<int,double,std::string>({1,2.5,std::string("ABC")});
printf("%d %.2lf %s\n", std::get<0>(t), std::get<1>(t), std::get<2>(t).c_str());
出力は次のようになります。
1 2.50 ABC
これは私のデスクトップでclang 3.2でテストされています
私の入力が役立つことを願っています:)