显然,不明确的调用不会在GCC上导致编译错误
Obviously ambiguous call does not cause a compilation error on GCC
我很惊讶GCC不认为以下程序中对foo()
的调用不明确:
#include <iostream>
struct B1 { bool foo(bool) { return true; } };
struct B2 { bool foo(bool) { return false; } };
struct C : public B1, public B2
{
using B1::foo;
using B2::foo;
};
int main()
{
C c;
// Compiles and prints `true` on GCC 4.7.2 and GCC 4.8.0 (beta);
// does not compile on Clang 3.2 and ICC 13.0.1;
std::cout << std::boolalpha << c.foo(true);
}
上面的函数调用在GCC 4.7.2和GCC 4.8.0(测试版(上编译并返回true
,而它在Clang 3.2和ICC 13.0.1上不会编译(正如我所料(。
这是">无需诊断"的情况,还是GCC中的错误鼓励参考C++11标准。
§7.3.3/3:
在用作成员声明的using声明中,嵌套名称说明符应命名所定义类的基类。如果这样的using声明命名构造函数,则嵌套名称说明符应命名所定义类的直接基类;否则它引入了通过成员名称查找(10.2,3.4.3.1(找到的声明集。
¶14:
…[注意:两个using声明可能会引入具有相同名称和相同参数类型的函数。如果对不合格函数名称的调用,函数重载解析选择了由此类using声明引入的函数,则函数调用格式错误。
¶16:
为了解决过载问题,通过using声明引入到派生类将被视为派生类的成员。
因此,using
声明是合法的,但正如您所说,函数是同一重载集中的对等函数,并且程序格式不正确。
正如您所说,程序中对foo(true)
的调用显然是模棱两可的;此外,根据§10.2,因此,应在使用时对其进行标记。(标记using
声明是不正确的;10.2(1(明确指出,名称的不明确使用是在查找时标记的,而不是在声明时标记的。(
将这个程序与类似的程序进行对比是很有趣的,类似的程序是一个公认的gcc错误的主题(从该错误报告中稍作修改,以使并行更清晰(:
#include <iostream>
struct A {
static int foo() {return 1;}
static int foo(char) { return 2;}
};
struct B1 : A {
// using A::foo;
};
struct B2 : A {
// using A::foo;
};
struct C : B1, B2 {
// using B1::foo;
// using B2::foo;
};
int main()
{
std::cout << C::foo();
}
上述程序是正确的;尽管有钻石继承,但foo
是A
的静态成员,因此它并不含糊。事实上,gcc编译它没有遇到任何麻烦。然而,取消对using A::foo
的两个实例的注释(这不会改变任何一个foo
(会导致gcc产生错误报告中记录的奇怪的重复错误。取消对C
内的两个using
声明的注释,这可能会触发本问题所涉及的另一个错误,然后屏蔽static function
错误并使程序重新编译。
clang似乎处理了这个程序的所有可能的变体,不管它值多少钱。
最后,请注意,(在原始程序中(C
中显式声明的foo(bool)
将胜过using
声明带入C
范围的任何foo(bool)
。我怀疑这两个错误都是错误记账的结果,同时试图跟踪每个类的作用域中的各种函数声明及其各自的出处(作为using
声明和函数声明的序列(。
- 在分配和发布递增循环迭代器时C++无限循环(gcc 错误?
- GCC 警告和 gcc 错误消息之间的区别
- 调试模板时出现问题.专门针对 Linux GCC 7、GCC 6、GCC 5、GCC 4.9 错误构建失败:模板参数 1
- typedef名称与可变模板参数名称一致时出现GCC错误
- 条件变量:wait_for.gcc错误
- 不可复制类数据成员的统一初始化导致gcc错误
- 在类中将不完整类型的unique_ptr初始化为 nullptr 时编译 gcc 错误
- GCC-7:错误:无法识别的命令行选项"-M64"
- C++ GCC 错误:"sqrtl"不是"std"的成员
- 在联盟中,不愿命名的未命名结构的成员是错误或GCC错误
- 尾随返回类型中带有 SFINAE 的 GCC 错误
- 与lambda一起使用虚拟继承在初始化列表中捕获此问题的GCC错误
- 通过指向成员的指针对嵌套访问进行编译时评估期间出现 GCC 错误
- 从成员变量访问静态 constexpr 成员,GCC 错误?
- std::seed_seq编译错误(GCC错误?)
- GCC 错误:如果已知函数正常返回,则函数可能是属性"pure"的候选者
- iostream GCC错误,转换为boost::filesystem::iostream for Windows
- GCC错误?链式方法,断开序列点
- 是否存在GCC错误:默认std :: function
- GCC 错误错误的 ELF 类:ELFCLASS64,尽管有 -m64 标志