@Xeo has an elegant and simple solution. However, if you want to have insert<> as a member function, you can use the following approach:
#include <set> #include <tuple> template<typename... Ts> struct my_sets : protected std::set<Ts>... { using types = std::tuple<Ts...>; template<int I, typename T> typename std::pair< typename std::set<typename std::tuple_element<I, types>::type>::iterator, bool> insert(T&& t) { return std::set<typename std::tuple_element<I, types>::type>::insert( std::forward<T>(t) ); } // ... // Function for retrieving each set... template<int I> typename std::set<typename std::tuple_element<I, types>::type>& get() { return *this; } };
And this is how you use it
#include <string> int main() { my_sets<int, double, std::string> s; s.insert<0>(42); s.insert<1>(3.14); s.insert<2>("Hello World!"); s.get<0>().insert(42); }
Note that the above solution does not allow multiple occurrences of the same type in the type list (which may or may not be desirable), although it can be fairly easily expanded to allow them:
#include <set> #include <tuple> namespace detail { template<int... Is> struct indices { typedef indices<Is..., sizeof...(Is)> next; }; template<int I> struct index_range { using type = typename index_range<I - 1>::type::next; }; template<> struct index_range<0> { using type = indices<>; }; template<int I, typename T> struct dummy : T { }; template<typename, typename... Ts> struct my_sets { }; template<int... Is, typename... Ts> struct my_sets<indices<Is...>, Ts...> : protected dummy<Is, std::set<Ts>>... { using types = std::tuple<Ts...>; template<int I, typename T> typename std::pair< typename std::set<typename std::tuple_element<I, types>::type>::iterator, bool > insert(T&& t) { return dummy<I, std::set<typename std::tuple_element<I, types>::type>>:: insert(std::forward<T>(t)); } template<int I> dummy<I, std::set<typename std::tuple_element<I, types>::type>>& get() { return *this; } }; } template<typename... Ts> using my_sets = detail::my_sets< typename detail::index_range<sizeof...(Ts)>::type, Ts... >;
And here is how you use it:
#include <string> int main() { my_sets<int, double, int, std::string> s; s.insert<0>(42); s.insert<1>(3.14); s.insert<2>(1729); s.insert<3>("Hello World!"); s.get<0>().insert(42); }