Неоднозначное введенное имя класса не является ошибкой - PullRequest
19 голосов
/ 11 августа 2011

То, что я читаю в стандарте C ++ относительно введенных имен классов, противоречит (на мой взгляд) поведению примера программы, которое я вскоре представлю. Вот что я читаю:

  • От 3,4 (пункт 3)

    Имя введенного класса класса (раздел 9) также считается член этого класса в целях сокрытия имени и поиска.

  • Из 9 (пункт 2)

    Имя класса вставляется в область, в которой оно объявлено сразу после того, как имя класса замечено. Имя класса также вставляется в область действия самого класса; это известно как впрыскивается класс имя. В целях проверки доступа имя введенного класса обрабатывается так, как если бы оно было публичным именем участника.

Исходя из этого, я понимаю, что следующий текст является правильно сформированным модулем перевода и успешно компилируется.

#include <vector>
class X: std::vector<int>
{
   vector mem;
};

Однако я бы предположил, что следующее должно было привести к ошибке, но это не

#include <vector>
class X: std::vector<int>, std::vector<char>
{
   vector mem; //compiles OK... mem is apparently std::vector<int>
};

Поскольку имя vector вводится как в std::vector<int>, так и std::vector<char>, как если бы оно было публичным именем члена, то оно должно наследоваться X, и поэтому имя vector в X должно быть неоднозначным. Я что-то упустил?

P.S. Я использую MSVC9.0

Ответы [ 2 ]

15 голосов
/ 11 августа 2011

Я нашел это! Это прямо в стандарте! Я был прав! Это должно быть неоднозначным!

Пункт 14.6.1 Абзац

Поиск, который находит имя введенного класса (10.2), может привести к неоднозначность в некоторых случаях (например, если она обнаружена в более чем один базовый класс). Если все найденные имена введенных классов ссылаются на специализации того же шаблона класса, и если имя сопровождается шаблоном-аргумент-списка, ссылка ссылается на Сам шаблон класса, а не его специализация, и не является неоднозначный. [Пример:

template <class T> struct Base { };
template <class T> struct Derived: Base<int>, Base<char> 
{ 
    typename Derived::Base b; // error: ambiguous typename 
    Derived::Base<double> d;  // OK 
};

- конец примера]

Итог: Это еще один компилятор Microsoft BUG . Отключение языковых расширений тоже не помогает.

4 голосов
/ 11 августа 2011

Нет, вы ничего не пропустили, и ваш компилятор, похоже, работает некорректно.Вы можете увидеть, как gcc обрабатывает это здесь: http://ideone.com/MI9gz

Его сообщение об ошибке:

prog.cpp:4:4: error: reference to 'vector' is ambiguous
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_vector.h:171:5: error: candidates are: class std::vector<char> std::vector<char>::vector
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_vector.h:171:5: error:                 class std::vector<int> std::vector<int>::vector
...