请考虑以下代码:
struct A {
int propose();
};
struct A1 : A {
int propose(int);
using A::propose;
};
struct B1 : A1 {
protected:
using A1::propose;
public:
using A::propose;
};
int main() {
B1().propose();
}
Run Code Online (Sandbox Code Playgroud)
让我们编译一下:g++ -std=c++11 main.cpp.
我使用GNU 4.8.1得到以下编译器错误:
main.cpp: In function 'int main()':
main.cpp:2:9: error: 'int A::propose()' is inaccessible
int propose();
^
main.cpp:18:18: error: within this context
B1().propose();
Run Code Online (Sandbox Code Playgroud)
但是,此代码在AppleClang 6.0.0.6000056中编译.
我明白没有必要using进入B1,(在我的代码中是必要的,但我using错误地得到了1 ).无论如何,为什么Clang编译呢?这是预期的吗?
Bar*_*rry 11
在[namespace.udecl]中,我们有:
当using声明将基类中的名称带入派生类范围时,派生类中的成员函数和成员函数模板将覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,parameter-type-list(8.3 0.5),CV-资格,和ref-限定符(如果有的话)在一个基类(而不是相互矛盾的).
标准明确指出引入的名称不会与基类中的名称冲突.但它没有提到引入相互冲突的名字.
该部分还说:
甲using声明是声明的,因此可以反复使用,其中(并且仅在哪里)多个声明是允许的.[例如:
Run Code Online (Sandbox Code Playgroud)struct B { int i; }; struct X : B { using B::i; using B::i; // error: double member declaration };- 末端的例子]
有趣的是,在下面的例子中,GCC很乐意编译它(并打印A),而Clang允许构造一个C但拒绝对foo的调用是不明确的:
struct A {
void foo() { std::cout << "A\n"; }
};
struct B {
void foo() { std::cout << "B\n"; }
};
struct C : A, B {
using A::foo;
using B::foo;
};
int main()
{
C{}.foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以简短的回答是 - 我怀疑标准中没有说明这一点,并且两个编译器都在做可接受的事情.我会避免为了一般的理智而编写这种代码.
| 归档时间: |
|
| 查看次数: |
583 次 |
| 最近记录: |