#c #templates #overloading #using #type-alias
#c #шаблоны #перегрузка #использование #тип-псевдоним
Вопрос:
Я хочу создать псевдоним типа array_t
. Это должно работать как для ограниченных, так и для неограниченных массивов. Я могу объявить это для каждого случая отдельно следующим образом:
// Type of an unbounded array of `T`
template <typename T>
using array_t = T[];
// Type of an array of `T` of size `Size`
template <typename T, size_t Size>
using array_t = T[Size];
Проблема в том, что оба не могут быть объявлены одновременно. Я думаю, что решением может быть использование какой-то специализации шаблона, но я не уверен, как ее использовать в этом случае.
Комментарии:
1. как вы решаете их использовать?
2. Для чего вам нужен этот псевдоним типа? Какую реальную проблему он должен решить?
3. @appleapple Я не планирую использовать
array_t
, я привел это как минимальный пример того, чего я пытаюсь достичь — «перегрузить» объявление псевдонима. Я мог бы привести более сложный пример, но этот показывает намерение.4. @enthusiastic_3d_graphics_pr… пожалуйста, предоставьте более сложный пример, вы даже не можете перегрузить обычное определение класса таким образом.
Ответ №1:
Согласно cppreference (https://en.cppreference.com/w/cpp/language/type_alias )
Невозможно частично или явно специализировать шаблон псевдонима.
Однако можно использовать пакет параметров шаблона, отличных от типа, поэтому мы можем использовать следующий трюк:
template <class T, size_t... Sizes>
struct array_t_helper
{ };
template <class T, size_t Size>
struct array_t_helper<T, Size>
{
using t = T[Size];
};
template <class T>
struct array_t_helper<T>
{
using t = T[];
};
template <typename T, size_t... Sizes>
using array_t = typename array_t_helper<T, Sizes...>::t;
Комментарии:
1. Потрясающий, умный трюк! Именно то, что мне было нужно, спасибо.
2. Я бы просто изменил основной шаблон, чтобы
t
он вообще не определялся, потому что егоvoid
наличие потенциально может вызвать некоторые проблемы, в то время как отсутствие его определения было бы удобнее для SFINAE.