Рассмотрим этот код,
template
struct Sample
{
typename T::X *x; //declare pointer to T's X
};
В приведенном выше коде ключевое слово typename
требуется компилятору , так что он может устранять неоднозначность между вложенными типами и вложенными значениями в шаблонах. Это означает, что в отсутствие ключевого слова typename
компилятор интерпретирует это как умножение T :: X на x,
T::X *x; //multiply T::X with x
Таким образом, в таких ситуациях, когда может возникнуть неоднозначность, ключевое слово typename
становится необходимостью для устранения двусмысленности. Но бывает немного ситуаций, когда сам контекст устраняет двусмысленность. В другом разделе обсуждаются контексты базового класса и параметров функций (последний не устраняет двусмысленность). В этой теме Я особенно хочу обсудить другие два контекста, которые кажутся однозначными , но мы все равно должны писать typename
,
typedef typename T::X xtype;
pX = new typename T::X;
В этих двух ситуациях ключевые слова typedef
и new
достаточно ясно дают компилятору понять, что все, что следует далее, является типом , не значением .
Итак, мой вопрос: почему компиляторам по-прежнему требуется ключевое слово typename
даже в однозначных ситуациях, например, когда мы используем typedef
и new
?
//typedef NOT followed by a type!
int typedef A;
Этот синтаксис просит меня немного изменить мой вопрос, чтобы то, что я пытаюсь сделать, было видно другим .
Подумайте об этом,
T::X typedef *x;
Итак, из контекста компилятору все еще достаточно ясно, что T :: X является типом, независимо от того, появляется ли он перед typedef
или после typedef
. Если C ++ не позволяет нам писать typedef 5 five
или typedef T :: value t_value
(где T :: value равно value ), наличие Сам typedef
устраняет все неоднозначности, поэтому typename
кажется ненужным требованием Стандарта (в таких ситуациях) . Тот же аргумент справедлив и для new
.
Кроме того, я написал шаблон класса, который использует эту структуру в качестве аргумента шаблона:
struct A
{
struct X { string name; };
static const int X = 100;
};
Я особенно хочу знать, если следующий код (из конструктор) правильный (переносимый) или нет,
//two interesting statements
pX = new typename T::X; //T::X means struct X
product = T::X * p; //but here, T::X means int X
Полный код здесь на ideone. Пожалуйста, ознакомьтесь с ним, прежде чем отвечать. : -)