#c #templates #c 17
#c #шаблоны #c 17
Вопрос:
Мне нужно написать специализацию шаблона, которая будет работать с указателями на массивы (эти вещи: char(*)[]
). И для этого мы напишем этот код
// our class
template<typename T>
struct CoolStruct
{
static void Print(); // will print "Default"
};
//one specialization for sized arrays
template<typename T, size_t S>
struct CoolStruct<T(*)[S]>
{
static void Print(); // will print "T(*)[sized]"
};
// and one for arrays without size
template<typename T>
struct CoolStruct<T(*)[]>
{
static void Print(); // will print "T(*)[]"
};
И когда в нашем коде мы сделаем что-то вроде этого:
int (*arrptr)[10];
CoolClass<decltype(arrptr)>::Print();
Консоль выведет «T (*)[sized]», как мы и ожидали (учитывая, что мы, конечно, написали реализацию для всех методов). Но что, если мы напишем наш код следующим образом:
int (**arrptr_d)[10];
CoolClass<decltype(arrptr_d)>::Print();
В этом случае консоль фактически выведет «Default». Мы могли бы написать другую специализацию, подобную этой:
template<typename T, size_t S>
struct CoolStruct<T(**)[S]>
{
static void Print(); // will print "T(*)[sized]"
};
но я хочу найти другое решение (я не хочу писать еще дюжину специализаций, когда мне нужно было бы использовать int(****)[]
). Итак, учитывая, что мы используем стандарт C 17, есть ли способ сделать такую вещь?
P.S. И да, извините за мой ужасный английский; это не мой родной язык.
Ответ №1:
Если вас не волнуют другие указатели, вы могли бы сделать частичную специализацию, которая делегирует двойные указатели на специализацию для одиночных указателей:
template<typename Pointee>
struct CoolStruct<Pointee**>{
static void Print(){
CoolStruct<Pointee*>::Print();
}
};