当 C++标准提供了将名称引入全局命名空间的 C 标头,这是否包括重载?
即将推出的 C++0x 标准的最终委员会草案表示:
每个 C 标头,每个标头都有一个 name.h 形式的名称,其行为就像 标准中的每个名称 库名称空间由相应的 cname 标头位于 全局命名空间范围。这是 未指定这些名称是否是 首先声明或定义在 的命名空间范围(3.3.6) 命名空间 std,然后注入 进入全局命名空间范围 显式使用声明 (7.3.3)。
早期的 C++ 标准的读法类似。
我的问题是,当 C++ 标头 #include
使用重载函数时,是否所有重载都是由 #include
引入的,因为重载不是单独的“名字”?
以下代码的行为在符合标准的 C 和 C++ 编译器之间是否应该有所不同?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void)
{
double arg = -2.5;
double result = abs(arg) / 3;
printf("%f\n", result);
return 0;
}
编译就绪测试用例:
- C++
math.h
和stdlib.h
: http://ideone.com/pmD4t - C
math.h
和stdlib.h
:http://ideone.com/Sflpn - C++
cmath
和cstdlib
:http://ideone.com/yI07m - 仅 C++
cmath
:http://ideone.com/KrS3W
从该测试来看,C++ math.h
的行为类似于 C,而不是 C++ cmath
。
但在 Visual C++ 2010 上,C++ math.h
的行为类似于 C++ cmath
。
以及与 Comeau try-it-out 一起使用的编译时金丝雀:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
template<typename T> struct typecheck {};
template<> struct typecheck<int> { enum { value = 1 }; };
template<typename T>
typecheck<T> f(const T& t) { return typecheck<T>(); }
int main(void)
{
double arg = -2.5;
auto result = abs(arg) / 3;
printf("%d\n", f(result).value);
return 0;
}
结果:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 15: error: class "typecheck<double>" has no member "value"
printf("%d\n", f(result).value);
^
1 error detected in the compilation of "ComeauTest.c".
Comeau 同意 Visual C++。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,所有重载都应该放入全局命名空间中。我的理解是,math.h 标头看起来像这样:
所以,是的:示例程序的行为在编译为 C 程序时与编译为 C++ 程序时不同。作为 C++ 程序,它将从
调用std::abs(double)
。作为 C 程序,它将从
调用abs(int)
(这是 C 标准中唯一的abs
函数)库,因为 C 不支持函数重载)。Yes, all overloads should be brought into the global namespace. My understanding is that the
math.h
header is intended to look something like:So, yes: the behavior of your example program is different when compiled as a C program than when compiled as a C++ program. As a C++ program, it will call
std::abs(double)
from<math.h>
. As a C program it will callabs(int)
from<stdlib.h>
(this is the onlyabs
function in the C Standard Library, since C does not support function overloading).