19

我在 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 继承,因此vectorin 中的名称X应该是模棱两可的。我错过了什么吗?

PS我正在使用MSVC9.0

4

2 回答 2

17

我找到了!它就在标准中!我是对的!应该是模棱两可的!

第 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。禁用语言扩展也无济于事。

于 2011-08-11T11:55:56.423 回答
4

不,您没有遗漏任何东西,而且您的编译器似乎有问题。您可以在此处查看 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
于 2011-08-11T11:52:21.113 回答