c++:从类继承是否会将其带入命名空间
C++: Does inheriting from a class bring it into the namespace?
下面是一些做作的示例代码:
template<typename T> void Do(T arg) { (void)arg->b; }
namespace A {
struct Foo { int a; };
}
namespace B {
struct Foo { int b; };
struct Bar : A::Foo {
void Blah() { Do((Foo *)0); }
};
}
当使用gcc 4.8.2编译时(clang给出类似的错误):
namespacebug.cpp: In instantiation of ‘void Do(T) [with T = A::Foo*]’:
namespacebug.cpp:10:34: required from here
namespacebug.cpp:1:39: error: ‘struct A::Foo’ has no member named ‘b’
template<typename T> void Do(T arg) { (void)arg->b; }
^
请注意,在错误中它指的是T = A::Foo
,即使在调用站点,我在命名空间B
中创建了Foo
。如果我删除基类decl (: A::Foo
),那么所有编译都很好。
这似乎表明继承A::Foo
以某种方式将其带入我的命名空间并将其与我使用的Foo
相匹配?是什么c++"特性"导致了这种情况?
(当然,这个问题可以很容易地通过命名空间我使用Foo
来解决,但这不是问题。)
由于使用了inject -class-name规则,类名就像成员一样可见。
9/2
在类名出现后,立即将类名插入声明它的作用域。类名也被插入到类本身的作用域中;这就是所谓的注入类名。出于访问检查的目的,注入的类名被视为公共成员名。
因此,好像类A::Foo
包含一个成员Foo
,该成员将类型命名为A::Foo
。由于Bar::Blah()
中的名称查找在名称空间成员之前考虑Bar
的基本成员,因此Foo
的名称查找查找注入的class-name,它命名A::Foo
。
从类继承是否将其带入命名空间?
。如果在类中查找名称失败,则在基类中继续查找。
10.2查找成员名
…
5否则(即
C
不包含f
的声明或结果声明集为空),S(f,C)
初始为空。如果C
有基类,计算f
在每个直接基类子对象Bi
中的查找集,并依次将每个查找集S(f,Bi)
合并为S(f,C)
。
成员名查找也包括嵌套类型查找。在同一部分的后面,我们发现:
9 [注:可以明确地找到基类T中定义的静态成员、嵌套类型或枚举数,即使对象具有多个T类型的基类子对象。两个基类子对象共享它们共同虚基类的非静态成员子对象。 -end note]
- 是否可以将函数导入命名空间,但不能导出它?
- VS2017 是否更改了 C++ 中访问 C# 命名空间的方式?
- C++ - 是否将常量幻数放入命名空间
- 初始化命名空间中的变量是否类似于将它们初始化为类成员?
- 是否将命名空间范围文件本地 (.cpp) 常量放在匿名命名空间中
- c++ 内联友元函数是否会导致命名空间之间的名称隐藏?
- 将以"_[a-z0-9]"开头和"using"的标识符导入全局命名空间是否定义良
- 是否可以在相同的命名空间中,但在不同的嵌套项目中定义具有相同名称的类
- 是否可以在 c ++ 中查看命名空间的所有内容?
- 是否有 GCC 警告,用于使用 C 库中的符号而不是通过命名空间 std?
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 使用显式命名空间限定符时模板实例化行为是否发生变化?
- 调用 ADL 时,表达式和命名空间之间是否会发生冲突
- winrt 命名空间是否具有控制台函数?
- 一个命名空间是否可以是另一个命名空间的成员
- 命名空间是否可以用作C++中的对象模板
- 在匿名命名空间中使用命名空间是否安全
- 隐藏第三方命名空间是否危险
- C++:当前命名空间是否覆盖其他命名空间
- c ++命名空间是否有类似".."?