根据标准在 N4296::13.3.3 [over.match.best]
中提供的示例
namespace A
{
extern "C" void f(int = 5);
}
namespace B
{
extern "C" void f(int = 5);
}
using A::f;
using B::f;
void use()
{
f(3); // OK, default argument was not used for viability
f(); // Error: found default argument twice
}
正如标准在 N4296::7.5/6 [dcl.link]
中所说:
Two declarations for a function with C language linkage with the same function name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same function.
我试着用我自己的例子来探索这样的事情:
#include <iostream>
namespace A
{
extern "C" void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}
namespace B
{
extern "C" void foo(int a = 5);
}
using A::foo;
using B::foo;
int main()
{
foo(); //Error
foo(2);
}
那么为什么我的示例有效?除非我在 A
命名空间中明确定义函数,否则我的示例和标准示例之间有什么区别?为什么这如此重要?
最佳答案
如评论中所述,标准示例与您的示例之间没有相关差异。正确实现标准的编译器会为两者发出诊断。
事实是,至少在 clang 和 Intel 中这显然是一个编译器错误,当您将示例编辑为无意义时可以看出这一点
namespace A
{
extern "C" void f(int = 5);
}
namespace B
{
extern "C" void f(int = 3); // different default argument
}
using A::f;
using B::f;
void use()
{
f(); // No error !
}
尽管有两个不同 默认参数,但不会生成错误甚至警告。使用其中一个默认参数,第一个用于 Intel,第二个用于 clang。
GCC 确实拒绝了这个荒谬的例子,所以没有快速简便的方法来验证它是否也是 GCC 中的一个错误,但这并没有改变它是的事实:如前所述,它默默地接受标准中的示例,其中标准指出应检测错误的位置。
关于c++ - 当我们调用 C 函数时,为什么不抛出编译器时间错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27683995/