2013-11-14 3 views
7

Этот код действителен C++ (11)?Вложенный класс, скрытый множественным наследованием

struct Base { 
    template <typename> 
    struct nested; 
}; 
struct Derived1 : Base { }; 
struct Derived2 : Base { }; 
struct Derived3 : Derived1, Derived2 { }; 

typedef Derived3::nested<int> xxx; 

Что я знаю

выше код не компилировать с:

  • компании Apple LLVM 5.0 (лязг-500.2.75)
  • Clang 3,4

Но он успешно компилируется с:

  • GCC 4.9.0 20131110 (экспериментальный)
  • НКУ 4,8

Кроме того, если я изменю nested типа к типу нешаблонном, т.е.

struct Base { 
    struct nested; 
}; 
... 
typedef Derived3::nested xxx; 

затем он работает с указанными выше компиляторами.

[править] Изменение nested шаблона на-структуру шаблона псевдонима также ничего не меняет;

template <typename> struct dependent { struct type; }; 
struct Base { 
    template <typename T> 
    using nested = typename dependent<T>::type; 
}; 

дает те же результаты с вышеуказанными компиляторами. [конец править]

От N3242 §10.1 [class.mi]

Класс может быть косвенным базовым классом более чем один раз и может быть прямым и косвенным базовым классом. Есть ограниченные вещи, которые можно сделать с таким классом. Нестатические члены данных и функции-члены прямого базового класса не могут быть указаны в области производного класса. Тем не менее, статические члены, перечисления и типы могут быть однозначно упомянуты.

Я думаю это означает, что код должен быть действительным, но я не уверен.

+0

Я искал [отчет об ошибке] (https://bugs.llvm.org/show_bug.cgi?id=17929) (id 17929), заполненный OP, поскольку ошибка (?) Кажется все еще там в clang 5.0 0,1. К сожалению, ответов не было. – Caninonos

ответ

0

Это прекрасно НКУ либо право/более полезным (он прилипает к стандарту очень сильно)

Он не может понять, почему определение будет неоднозначным, потому что вы говорите о типе не член, и тип равен, если их имена совпадают в C++ (имена являются один подогнана формой типов участвуют и такая)

Добавление:

Было бы неправильно, если «вложенный» и «вложенные» в другой базе были разными. Это структура, а не typedef или использование (которые скопированы)

GCC будет скулить, если что-то неоднозначно, попробуйте с -pedantic, если вы хотите сделать его сукой, даже если это не так. Я не вижу причин, по которым это должно быть отклонено, даже если GCC просто разрешительна.

+0

Я не уверен, что понимаю ваше добавление. Вы имеете в виду, что код может быть неоднозначным, если «вложенный» был, например, псевдоним шаблона C++ 11 вместо шаблона struct? –

+0

@ LouisDionne да, потому что они могли бы псевдоним разных вещей. Они рассматриваются как члены во время разбора, потому что применяются одни и те же правила, проблема алмаза поднимает голову, с которой вы хотели использовать. –

+0

@ LouisDionne я ответил на вопрос? .... –

Смежные вопросы