Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous injected class name is not an error

What I read in the C++ standard about injected class names contradicts (as I see it) with the behavior of a sample program I will present shortly. Here's what I read:

  • From 3.4 (paragraph 3)

    The injected-class-name of a class (clause 9) is also considered to be a member of that class for the purposes of name hiding and lookup.

  • From 9 (paragraph 2)

    A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.

From these I understand that the following is a well-formed translation unit and it compiles successfully.

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

However, I would suppose that the following should have produced an error, but it doesn't

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

Since the name vector is injected into both std::vector<int> and std::vector<char> as as if a public member name, then it should be inherited by X and therefore the name vector in X should be ambiguous. Am I missing something?

P.S. I am using MSVC9.0

like image 529
Armen Tsirunyan Avatar asked Aug 11 '11 11:08

Armen Tsirunyan


People also ask

What is ambiguity error?

Ambiguity errors occur when erasure causes two seemingly distinct generic declarations to resolve to the same erased type, causing a conflict.

What is ambiguity problem in c++?

When you derive classes, ambiguities can result if base and derived classes have members with the same names. Access to a base class member is ambiguous if you use a name or qualified name that does not refer to a unique function or object.

What does class name mean in C++?

Class: A class in C++ is the building block that leads to Object-Oriented programming. It is a user-defined data type, which holds its own data members and member functions, which can be accessed and used by creating an instance of that class. A C++ class is like a blueprint for an object.


2 Answers

I found it! It's right there in the standard! I was right! It should be ambiguous!

Clause 14.6.1 Paragraph

A lookup that finds an injected-class-name (10.2) can result in an ambiguity in certain cases (for example, if it is found in more than one base class). If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is followed by a template-argument-list, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous. [Example:

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 
};

—end example]

Bottom line: This is yet another Microsoft compiler BUG. Disabling language extensions doesn't help either.

like image 133
Armen Tsirunyan Avatar answered Sep 29 '22 00:09

Armen Tsirunyan


No, you are not missing anything, and your compiler seems to behave buggy. You can see how gcc handles it here: http://ideone.com/MI9gz

Its error message is:

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
like image 40
PlasmaHH Avatar answered Sep 28 '22 22:09

PlasmaHH