#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