我在C ++标准中读到的关于注入类名的内容与我将要提供的示例程序的行为相矛盾(我认为)。这是我读到的:
从3.4(第3段)
类的注入类名(第9节)也被认为是 为了名称隐藏和查找的目的,该类的成员。
从9(第2段)
将类名插入到声明它的作用域中 看到类名后立即。类名也是 插入到类本身的范围内;这被称为 注入的类名。出于访问检查的目的, 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继承,因此名称为vector
在X
中应该含糊不清。我错过了什么吗?
P.S。我正在使用MSVC9.0
答案 0 :(得分:15)
我找到了!它就在标准中!我是正确的! 应该含糊不清!
第14.6.1条第
段查找注入类名称(10.2)的查找可能会导致 在某些情况下的歧义(例如,如果发现超过 一个基类)。如果找到所有注入的类名 引用相同类模板的特化,如果名称 后跟一个template-argument-list,引用引用 类模板本身并不是它的特化,而不是 暧昧。 [例如:
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]
底线: 这是另一个 Microsoft编译器BUG 。禁用语言扩展也无济于事。
答案 1 :(得分: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