Тип класса, который имеет шаблон variadict в теле другого класса

#c #templates #variadic-templates

#c #шаблоны #variadic-шаблоны

Вопрос:

Я не эксперт в метапрограммировании шаблонов, и сейчас я как бы застрял. Любая помощь будет оценена.

В качестве введения. У меня есть класс (здесь немного упрощенный):

 template < int dim, int spacedim, int... structdims >
class TopologyInfo
{
}
  

Я могу создать экземпляр TopologyInfo с помощью функций:

 template < int dim, int spacedim, size_t... dims >
auto get_topology_info_imp_( std::integer_sequence< size_t, dims... > )
{
    return TopologyInfo< dim, spacedim, dims... >( );
}

template < int dim, int spacedim, int max_topo_dim_ >
auto get_topology_info( )
{
    return get_topology_info_imp_< dim, spacedim >(
      std::make_index_sequence< max_topo_dim_ >{} );
}
  

Это работает, если я использую его таким образом:

 auto t = get_topology_info< 3, 3, 3 >( );
  

Тип t TopologyInfo<3, 3, 0, 1, 2> это правильный.

Итак, теперь проблема: как сгенерировать тип t без использования auto , чтобы я мог использовать рассматриваемый класс в качестве члена другого класса? Мне кажется, что я не совсем понимаю механизмы, лежащие std::index_sequence в основе, и что решение должно быть очевидным.

Комментарии:

1. decltype(get_topology_info< 3, 3, 3 >( ))

2. Что ж, это действительно работает. Раньше я decltype проверял тип, но никогда не думал, что смогу использовать его таким образом. Большое вам спасибо.

Ответ №1:

auto это просто место для фактического типа. Когда вы пишете

 auto t = get_topology_info< 3, 3, 3 >( );
  

тогда t имеет некоторый определенный тип. Тот факт, что вы использовали auto , этого не меняет.

Если фактический тип слишком громоздкий, чтобы его можно было прописать, или его трудно узнать, вы также можете использовать auto s cousin decltype . Например, это то же самое, что и выше:

 decltype( get_topology_info< 3, 3, 3>( )) t = get_topology_info< 3, 3, 3>( );
  

или, если у вас уже есть экземпляр:

 decltype( t ) s = get_topology_info< 3, 3, 3>( );
  

Для члена класса вы можете использовать псевдоним:

 using some_meaningful_name = decltype( get_topology_info< 3, 3, 3>( ) );
  

Затем

 struct foo {
   some_meaningful_name bar;
};
  

Комментарии:

1. Это работает, кроме using some_meaningful_name = get_topology_info< 3, 3, 3>( ); . Это decltype( ) все еще необходимо для функции.

2. @szynka12 о, извините, это опечатка, исправлено

Ответ №2:

Просто расширение idclev ответа:

Если вы get_topology_info много раз используете в своем коде с разными значениями, тогда вы можете захотеть преобразовать его в свой собственный тип:

 template <int A, dim, int spacedim, int max_topo_dim>
using some_meaningful_name = decltype(get_topology_info<dim, spacedim, max_topo_dim>());
  

Итак, теперь мы можем просто сказать:

 some_meaningful_name<3,3,3> member