Я не вижу элегантного способа перебора простых классов, таких как Derived1
, Derived2
, Derived3
и т. Д.
Но отличается, если вы можете шаблонизировать свои производные классы, добавив индекс шаблона, следующим образом или аналогичным образом
template <std::size_t>
struct Derived : public Base
{ Derived (int id) : Base{id} {} };
Если вы также можете использовать C ++ 14, вы можете использовать std::make_index_sequence
/ std::index_sequence
следующим образом
template <std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Derived<Is+1u>{Is}...); }
template <std::size_t N>
auto make_derives_tuple ()
{ return make_helper(std::make_index_sequence<N>{}); }
Ниже приводится полный пример компиляции
#include <tuple>
#include <utility>
#include <type_traits>
struct Base
{ Base (int) {} };
template <std::size_t>
struct Derived : public Base
{ Derived (int id) : Base{id} {} };
template <std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Derived<Is+1u>{Is}...); }
template <std::size_t N>
auto make_derives_tuple ()
{ return make_helper(std::make_index_sequence<N>{}); }
int main()
{
auto t = make_derives_tuple<3u>();
using T0 = decltype(t);
using T1 = std::tuple<Derived<1u>, Derived<2u>, Derived<3u>>;
static_assert( std::is_same<T0, T1>::value, "!" );
}
Если вы не можете шаблонизировать (добавить индекс) производные классы, лучшее, что я могу себе представить, - передать требуемые производные классы в виде списка переменных шаблона в make_derived_tuple()
.
Решение становится
template <typename ... Ts, std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Ts{Is}...); }
template <typename ... Ts>
auto make_derives_tuple ()
{ return make_helper<Ts...>(std::index_sequence_for<Ts...>{}); }
Ниже приведен полный пример компиляции (где я переименовал A
, B
, C
и D
производные классы
#include <tuple>
#include <utility>
#include <type_traits>
struct Base
{ Base (int) {} };
struct A : public Base
{ A (int id) : Base{id} {} };
struct B : public Base
{ B (int id) : Base{id} {} };
struct C : public Base
{ C (int id) : Base{id} {} };
struct D : public Base
{ D (int id) : Base{id} {} };
template <typename ... Ts, std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Ts{Is}...); }
template <typename ... Ts>
auto make_derives_tuple ()
{ return make_helper<Ts...>(std::index_sequence_for<Ts...>{}); }
int main()
{
auto t = make_derives_tuple<A, B, C, D>();
using T0 = decltype(t);
using T1 = std::tuple<A, B, C, D>;
static_assert( std::is_same<T0, T1>::value, "!" );
}