Вопрос

Кто-нибудь знает, почему объявления использования не работают для импорта имен типов из зависимых базовых классов?Они работают для переменных-членов и функций, но, по крайней мере, в GCC 4.3, они игнорируются для типов.

template <class T>
struct Base
{
  typedef T value_type;
};

template <class T>
struct Derived : Base<T>
{
  // Version 1: error on conforming compilers
  value_type get();

  // Version 2: OK, but unwieldy for repeated references
  typename Base<T>::value_type get();

  // Version 3: OK, but unwieldy for many types or deep inheritance
  typedef typename Base<T>::value_type value_type;
  value_type get();

  // Version 4: why doesn't this work?
  using typename Base<T>::value_type;
  value_type get(); // GCC: `value_type' is not a type
};

У меня есть базовый класс с набором определений типов в стиле распределителя, которые я хотел бы наследовать на нескольких уровнях наследования.Лучшее решение, которое я нашел на данный момент, — это версия 3, указанная выше, но мне любопытно, почему версия 4 не работает.GCC принимает декларацию использования, но, похоже, игнорирует ее.

Я проверил стандарт C++, C++ Prog.Ланг.3-е изд.[Stroustrup] и шаблоны C++ [Vandevourde, Josuttis], но ни в одном из них, похоже, не рассматривается вопрос о том, можно ли применять объявления using к зависимым типам базовых классов.

Если вам поможет другой пример, здесь задают тот же вопрос, но на самом деле не ответил в списке рассылки GCC.Спрашивающий указывает, что он видел «использование имени типа» где-то еще, но GCC, похоже, не поддерживает его.У меня нет другого соответствующего компилятора, чтобы протестировать его.

Это было полезно?

Решение

Как указывает Ричард Корден, этот вопрос рассматривался в Отчеты о дефектах стандартного базового языка C++ после ратификации стандарта 2003 г.: Как ключевые слова типа/шаблона взаимодействуют с объявлениями использования?

Предлагаемая резолюция (апрель 2003 г., пересмотрено в октябре 2003 г.):

Добавьте новый абзац в нижнюю часть 7.3.3 [namespace.udecl]:

Если в использовании декларации используется тип ключевого слова и определяет зависимое имя (14.7.2 [temp.dep]), имя, введенное с использованием декларации, рассматривается как имя Typedef (7.1.3 [dcl.typedef])) Полем

Этот текст, похоже, не встречается во втором издании стандарта от 15 октября 2003 г.

GCC еще не выполняет эту резолюцию, как поясняется в ошибка 14258:

------- Комментарий № 3 от Giovanni Bajo 2004-02-27 12:47 что это тип, который импортируется через него.Я полагаю, что это работало благодаря неявному расширению имени типа.

Дублировать ошибка 21484 указывает, что «использование имени типа» работает на компиляторах Comeau и Intel.Поскольку MSVC рассматривает все имена как зависимые, эта конструкция не нужна (но разрешена) для этого компилятора.


Зафиксированный в GCC 4.7 от 13 декабря 2011 г.!

Другие советы

Вы не включили спецификатор доступа (public/protected/private) в шаблон Base перед объявлением typedef для Base::value_type.В результате по умолчанию он является закрытым и недоступен в классах, производных от Base.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top