Использование ключевого слова typename с typedef и new

Рассмотрим этот код,

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. Пожалуйста, ознакомьтесь с ним, прежде чем отвечать. : -)

20
задан Community 23 May 2017 в 11:45
поделиться