@Xeoには、エレガントでシンプルなソリューションがあります。insert<>
ただし、メンバー関数として使用する場合は、次の方法を使用できます。
#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;
}
};
そして、これはあなたがそれをどのように使うかです
#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);
}
上記のソリューションでは、タイプリストに同じタイプを複数回出現させることはできませんが(これは望ましい場合と望ましくない場合があります)、非常に簡単に拡張して許可することができます。
#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...
>;
そして、これはあなたがそれをどのように使うかです:
#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);
}