不明确的注入类名不是错误

Ambiguous injected class name is not an error

本文关键字:错误 注入 不明确      更新时间:2023-10-16

我在c++标准中读到的关于注入类名的内容(在我看来)与我即将介绍的示例程序的行为相矛盾。以下是我读到的内容:

  • 出自3.4(第3段)

    类的注入类名(第9条)也被认为是类的成员,用于隐藏名称和查找。

  • 来自9(第2段)

    类名被插入到声明它的作用域中紧跟在类名之后。类名是also插入类本身的作用域;这被称为injected-class-name。为了进行访问检查inject -class-name被视为公共成员名。

从这些我了解到,下面是一个格式良好的翻译单元,它编译成功。

#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继承,因此X中的名称vector应该是不明确的。我错过什么了吗?

注:我使用的是MSVC9.0

我找到了!就在标准里!我是对的!应该是有歧义的!

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

端例子)

底线:这是另一个微软编译器错误。禁用语言扩展也没有帮助。

不,您没有错过任何东西,并且您的编译器似乎行为错误。您可以在这里看到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