Использование 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 ответа:
Компилятор уже знает, что
T
является типом (class T
), поэтому в первом случае вам не нужен квалификаторtypename
. OTOH, компилятор не знает заранее, чтоT::ElementType1
является типом; это зависит от того, что T в конечном итоге будет.
typename
может использоваться только для квалификации определенного имени; это не так. примените имя, непосредственно следующее за ним, но к определенному имени, то есть в:typedef typename T::X x;
typename
относится кX
, а не кT
. По этой причине, он является только законным (в этом использовании) перед квалифицированными именами. Неполные имена должно быть в контексте, где компилятор может знать, является ли имя a типа или нет. (На практике это проблема только в типах, определенных в зависимый базовый класс, и они могут быть квалифицированный.)