I tried to compile the following snippets with gcc4.7
vector > vp = {{1,\'a\'},{2,\'b\'}};
//For pair vector, it works like a char
This is actually doable, with c++11 features.
Yes the initializer_list wants all its element to be of the same type. The trick is that we can create a wrapper class that can be static_cast
to all the types we want. This is easy to achieve:
template
class MultiTypeWrapper {
};
template
class MultiTypeWrapper {
public:
MultiTypeWrapper() {}
MultiTypeWrapper(const H &value) : value_(value) {}
operator H () const {
return value_;
}
private:
H value_;
};
template
class MultiTypeWrapper
: public MultiTypeWrapper {
public:
MultiTypeWrapper() {}
MultiTypeWrapper(const H &value) : value_(value) {}
// If the current constructor does not match the type, pass to its ancestor.
template
MultiTypeWrapper(const C &value) : MultiTypeWrapper(value) {}
operator H () const {
return value_;
}
private:
H value_;
};
With the implicit conversion constructors, we can pass something like {1,2.5,'c',4} to an initializer_list (or vector, which implicitly converts the initializer_list) of type MultiTypeWrapper. This means that we can not write a function like below to accept such intializer_list as argument:
template
std::tuple create_tuple(std::vector > init) {
....
}
We use another trick to cast each value in the vector to its original type (note that we provide implicit conversion in the definition of MultiTypeWrapper
) and assign it to the corresponding slot in a tuple. It's like a recursion on template arguments:
template
class helper {
public:
static void set_tuple(std::tuple &t, const std::vector >& v) {
std::get(t) = static_cast >::type>(v[ind]);
helper<(ind-1),T...>::set_tuple(t,v);
}
};
template
class helper<0, T...> {
public:
static void set_tuple(std::tuple &t, const std::vector >& v) {
std::get<0>(t) = static_cast >::type>(v[0]);
}
};
template
std::tuple create_tuple(std::vector > init) {
std::tuple res;
helper::set_tuple(res, init);
return res;
}
Note that we have to create the helper class for set_tuple
since c++ does not support function specialization. Now if we want to test the code:
auto t = create_tuple({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());
The output would be:
1 2.50 ABC
This is tested on my desktop with clang 3.2
Hope my input helps :)