Двусмисленото инжектирано име на клас не е грешка

Това, което прочетох в стандарта C++ за имена на инжектирани класове, противоречи (както го виждам) с поведението на примерна програма, която ще представя скоро. Ето какво прочетох:

  • #P2#
    #P3#
  • #P4#
    #P5#

От тях разбирам, че следното е добре оформена единица за превод и се компилира успешно.

#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


person Armen Tsirunyan    schedule 11.08.2011    source източник
comment
Втората клауза не се ли отнася до X във вашия пример? т.е. дали името на инжектиран-клас не е X, а не vector? Мисля, че случаят е такъв и ако е така, кавичките са без значение за кода, но въпреки това поведението на този компилатор не изглежда правилно или няма причина да се предпочита std::vector<int> пред std::vector<char> и това означава, че трябва да има неяснота грешка се задейства.   -  person David Rodríguez - dribeas    schedule 11.08.2011
comment
@David: В клас X да, но vector се инжектира като публично име и в двете бази... Така че трябва да е видимо (и двусмислено) и вътре в X - както в първия пример   -  person Armen Tsirunyan    schedule 11.08.2011
comment
@Armen Tsirunyan: За std::vector, Име на клас се вмъква в обхвата, в който е деклариран, веднага след като се види името на класа.: std namespace; Името на класа също се вмъква в обхвата на самия клас; това е известно като injected-class-name.: std::vector шаблон. Все още мисля, че тези цитати не са свързани с конкретния примерен код.   -  person David Rodríguez - dribeas    schedule 11.08.2011
comment
@David: тъй като името на инжектирания клас е инжектирано с публична видимост, то е достъпно за производни класове, което се случва тук.   -  person Matthieu M.    schedule 11.08.2011
comment
:) Благодаря @Matthieu, не гледах отвъд първия ред код :)   -  person David Rodríguez - dribeas    schedule 11.08.2011
comment
@ArmenTsirunyan: винаги се позовавайте на повече от компилатори! И особено не работете само с бъги VC компилатор!   -  person Gob00st    schedule 09.10.2012


Отговори (2)


Намерих го! Има го точно там в стандарта! Бях прав! Трябва да е двусмислено!

Клауза 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. Деактивирането на езиковите разширения също не помага.

person Armen Tsirunyan    schedule 11.08.2011

@janis: вижте въпроса ми, добавих заявката и отговора
person PlasmaHH    schedule 11.08.2011
comment
А, да, наистина! Току-що сам намерих цитата от стандарта (вижте отговора ми) - person Armen Tsirunyan; 11.08.2011