Подтвердить что ты не робот

Почему невозможно перегрузить шаблоны классов?

Чтение этого вопроса заставило меня задуматься: есть ли техническая причина отказа от перегрузок шаблонов классов?

При перегрузке я имею в виду несколько шаблонов с одинаковыми именами, но разные параметры, например

template <typename T>
struct Foo {};

template <typename T1, typename T2>
struct Foo {};

template <unsigned int N>
struct Foo {};

Компилятор справляется с обработкой перегруженных функций и шаблонов функций, не могли бы ли быть применены те же методы (например, манипулирование именами) к шаблонам классов?

Сначала я подумал, что, возможно, это вызовет некоторые проблемы неоднозначности при использовании идентификатора шаблона в одиночку, но единственный раз, когда это может произойти, это передать его как аргумент шаблона шаблона, поэтому тип параметра можно использовать для выберите соответствующую перегрузку:

template <template <typename> class T>
void A {};

template <template <unsigned int> class T>
void B {};

A<Foo> a; // resolves to Foo<T>
B<Foo> b; // resolves to Foo<N>

Считаете ли вы, что такая функция может быть полезна? Есть ли какие-то "хорошие" (т.е. Технические) причины, почему это невозможно в текущем С++?

4b9b3361

Ответ 1

Раздел 12.5 из Шаблоны в полном руководстве (Amazon) содержит эту цитату:

Вы можете законно задаться вопросом, почему только шаблоны классов могут быть частично специализированы. Причины в основном исторические. Вероятно, возможно определить тот же механизм для шаблонов функций (см. Главу 13).

В некотором смысле эффект шаблонов функций перегрузки аналогичен, но есть и некоторые тонкие различия. Эти различия главным образом, связано с тем, что основной шаблон должен быть при поиске используется. Специализация рассматривается только после этого, чтобы определить, какая реализация должна быть используемый.

Напротив, все перегруженные функциональные шаблоны должны быть приведены в перегрузку, установленную, просматривая их, и они могут произойти из разные пространства имен или классы. Это увеличивает вероятность непреднамеренно перегружает имя шаблона.

И наоборот, это также позволяет разрешить форму перегрузки шаблонов классов. Вот пример:

// invalid overloading of class templates
template<typename T1, typename T2> class Pair; 
template<int N1, int N2> class Pair; 

Однако, похоже, нет насущной необходимости такой механизм.

Кроме того, Проект и эволюция С++ (Amazon) содержит эту цитату в разделе 15.10.3

Поэтому я пришел к выводу, что нам нужен механизм для "специализации шаблоны. Это можно сделать либо путем принятия общей перегрузки или каким-то более конкретным механизмом. Я выбрал конкретный механизм потому что я думал, что прежде всего обращаюсь к нарушениям, вызванным неровности в C и потому что предложения о перегрузке неизменно создает вопль протестов. Я пытался быть осторожным и консервативны; Теперь я считаю, что ошибка. Специализация первоначально была определена ограниченная и аномальная форма перегрузки которые плохо соответствуют остальной части языка.

Смелый акцент мой. Я интерпретирую это как высказывание о том, что функция перегрузки функции сложнее реализовать (и получить права пользователей), чем специализация класса. Так что, вероятно, никаких реальных технических препятствий (аналогичных для частичной специализации шаблонов функций), а исторической аварии.

Ответ 2

Вы не можете использовать параметр типа "перегрузка", параметр типа non-type и шаблон шаблона, но вы можете специализировать вариационный шаблон:

template <typename... T>
struct Foo;

template <typename T1>
struct Foo<T1> {};

template <typename T1, typename T2>
struct Foo<T1,T2> {};