В C ++ 11 вы можете создать «псевдоним типа», выполнив что-то вроде
template <typename T>
using stringpair = std::pair<std::string, T>;
Но это отклонение от ожидаемого шаблона typedef:
template <typename T>
typedef std::pair<std::string, T> stringpair;
Таким образом, возникает вопрос: зачем им нужен новый синтаксис? что не работало со старым typedef
синтаксис?
Я понимаю, что последний бит не компилируется, но почему его нельзя скомпилировать?
Из предложения WG21 N1489 Шаблон псевдонимов (Страуструп и Дос Рейс):
Было предложено (повторно) использовать ключевое слово
typedef
как сделано в
статья [4] для введения шаблонных псевдонимов:template<class T> typedef std::vector<T, MyAllocator<T> > Vec;
Эта нотация имеет преимущество использования ключевого слова, уже известного
введите псевдоним типа. Тем не менее, он также отображает несколько недостатков
среди которых путаница с использованием ключевого слова, известного для введения
псевдоним для имени типа в контексте, где псевдоним не обозначает
тип, но шаблон; Vec не является псевдонимом для типа, и не должен
быть взятым для typedef-имени. Имя Vec — это имя для семьи
std::vector<o, MyAllocator<o> >
где пуля является заполнителем
для имени типа. Следовательно, мы не предлагаем синтаксис typedef.С другой стороны, предложение
template<class T> using Vec = std::vector<T, MyAllocator<T> >;
можно читать / интерпретировать как: теперь я буду использовать
Vec<T>
как
синоним дляstd::vector<T, MyAllocator<T> >
, С этим чтением
Новый синтаксис для псевдонимов кажется достаточно логичным.
Документ [4], упомянутый в приведенной выше цитате, был предварительным предложением WG21. N1406 Предлагаемое дополнение к C ++: Шаблоны Typedef (Херб Саттер). Он использует как другой синтаксис (typedef
против using
), а также другую номенклатуру (шаблоны typedef или псевдонимы шаблонов). Предложенный Херб синтаксис не сделал этого, но номенклатуру иногда можно найти в неформальных дискуссиях.
Я просто сослался на самого Страуструпа:
http://www.stroustrup.com/C++11FAQ.html#template-alias
Ключевое слово using используется для получения линейного обозначения «name, за которым следует
к чему это относится. «Мы попробовали с обычным и запутанным
Решение typedef, но так и не удалось получить полное и согласованное
Решение, пока мы не остановились на менее смутном синтаксисе.
(Tl; д-р: using
поддерживает шаблоны, тогда как typedef
не.)
Как вы уже знаете, разница между двумя примерами без шаблонов ничего
[C++11: 7.1.3/2]:
ЬурейеЕ имя также может быть введен псевдоним декларации. Идентификатор послеusing
Ключевое слово становится ЬурейеЕ имя и необязательный Атрибут спецификатор-сл следующий за идентификатором относится к этому ЬурейеЕ имя. Он имеет ту же семантику, как если бы он был введенtypedef
спецификатор. В частности, он не определяет новый тип и не должен появляться в тип-идентификатор.
Тем не менее, шаблон typedef
с не существует!
[C++11: 14.5.7/1]:
Шаблон декларирование в котором декларация является псевдоним декларации (Раздел 7) объявляет идентификатор как шаблон псевдонима. Шаблон псевдонима — это имя для семейства типов. Имя шаблона псевдонима является Имя Шаблона.
Почему они просто не использовали повторно typedef
синтаксис? Ну я думаю typedef
это просто «старый» стиль и, учитывая использование using
в других контекстах было решено, что новые функциональные using
Форма для согласованности.
Еще одна причина для нового синтаксиса — typedefs для функций, массивов и подобных конструкций становятся немного более понятными.
Ссылка на массив до / после:
typedef int(&my_type)[3];
using my_type = int(&)[3];
Массив указателей на функции до / после:
typedef void(*my_type[3])();
using my_type = void(*[3])();