Использование typedef и typename внутри шаблона


Я хочу определить имя типа в шаблонном классе, которое я могу использовать в другом месте для ссылки на тип члена в классе.

template <class T>
class CA
{
public:
    //typedef typename T::iterator iterator_type;
    typedef typename T ElementType1; // compile error on this line
    //typedef T ElementType2;

    T m_element;
};

И использовать его так:

template <class T>
class CDerived : public CBase<typename T::ElementType1>
{
 //...
};

И объявлять объекты типа:

typedef CDerived<CA> MyNewClass;

Разве это невозможно? У меня есть код, который правильно компилируется под VS2010, но не под Xcode, который использует строку:

typedef typename T ElementType1;

Очевидно, компилятор ожидает полное имя после typename, но я не вижу, как это может быть для шаблона тип.

Я не понимаю разницы между ElementType1 и ElementType2 в этом контексте.

Я рассмотрел много вопросов о переполнении стека, но большинство из них, казалось, касались только такого типа объявления, как iterator_type в моем примере.

2 4

2 ответа:

Компилятор уже знает, что T является типом (class T), поэтому в первом случае вам не нужен квалификатор typename. OTOH, компилятор не знает заранее, что T::ElementType1 является типом; это зависит от того, что T в конечном итоге будет.

typename может использоваться только для квалификации определенного имени; это не так. примените имя, непосредственно следующее за ним, но к определенному имени, то есть в:

typedef typename T::X x;

typename относится к X, а не к T. По этой причине, он является только законным (в этом использовании) перед квалифицированными именами. Неполные имена должно быть в контексте, где компилятор может знать, является ли имя a типа или нет. (На практике это проблема только в типах, определенных в зависимый базовый класс, и они могут быть квалифицированный.)