【发布时间】:2021-07-07 18:52:54
【问题描述】:
我们知道,在其中定义了另一个同名实体的范围内,命名空间成员名称的“使用声明”会导致编译时错误:“符号 x 已定义”。
在“使用声明”出现的点检测到错误,而不是像“使用指令”那样出现在使用点。
类范围内的 using 声明只允许公开基类成员名称。
这是一个例子:
#include <iostream>
using namespace std;
struct Foo{
Foo(int x) : x_(x){}
int x_ = 0;
};
struct Bar{
Bar(int y) : y_(y){}
int y_ = 0;
};
struct FooBar : Foo, Bar{
using Foo::Foo; // inheriting Foo's ctors
using Bar::Bar; // inheriting Bar's ctors
int x_ = 10;
// using Foo::x_; // error detected here
};
int main(){
FooBar fb(5); // error detected here
}
正如您在上面看到的,Foo::x_ 的 using 声明会在 using 出现时导致编译时错误,这没关系。
但是基类 Foo 和 Bar 构造函数的 using 声明直到 main 中的使用才发出错误?!!
- 通常 FooBar 继承 Foo(int);因此,当
using Bar::Bar;正常出现时,编译器会抱怨,但代码工作正常,直到我尝试使用该构造函数。FooBar(int)。
在继承了所有的构造函数之后,编译器定义了一个派生类ctor,并让它调用它的基类,将它的参数传递给它,就像我们这样写:
struct FooBar : Foo, Bar{
FooBar(int x) : Foo(x){}
FooBar(int x) : Bar(x){}
//...
};
那么为什么编译器允许这样的错误呢?并等到使用该 ctor 来标记歧义??
- 在我看来,这种情况下的 using 声明与 using 指令的作用相同。
【问题讨论】:
-
您说“基类 Foo 和 Bar 构造函数的 using 声明在 main 中使用之前不会发出错误?!!”好吧,它们会导致错误,请注释以下两行 FooBar fb(5);和 int x_ = 10;您将在使用 Bar::Bar; 时获得已经从 foo 继承的 bar 构造函数
-
不,这就是我发布这个问题的原因。
-
不是吗?你的意思是,当你评论这两行时,你没有得到错误??如果你没有收到错误,那一定是编译器设置
-
@ma1169:是的,当然。我已经说过了。我正在使用 gcc 和 clang。
标签: c++ gcc constructor multiple-inheritance using-declaration