Как «перегрузить» шаблонное объявление псевдонима в C ?

#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.