防止std命名空间之外的标准函数 [英] Prevent standard functions outside of std namespace

查看:222
本文介绍了防止std命名空间之外的标准函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只使用特定于C ++的头文件(例如< cstdlib> ),但是我仍然使用全局声明函数,而不仅仅是函数 std 命名空间。有没有一种方法,可能是一个编译器开关,以防止这种情况?



例如,下面的代码:

  #include< cstdlib> 
float random(){return 0.0f; }
int main(){return 0; }

无法在linux下编译,出现以下错误:

 > g ++ -c main.cpp main.o 
main.cpp:函数'float random()':
main.cpp:2:14:error:new declaration'float random()'
/usr/include/stdlib.h:327:17:error:ambiguates old declaration'long int random()'



 > clang ++ main.cpp -o main.o 
main.cpp:2:7:错误:仅在返回类型不同的函数不能重载
float random(){return 0.0f; }
/usr/include/stdlib.h:327:17:注意:前面的声明在这里
extern long int random(void)__THROW;

导致 stdlib.h 使用自己的随机函数来污染全局命名空间。

注意,编译时我不会遇到这些问题在Windows上,使用Visual Studio。

解决方案


  1. < cstdlib> 将始终填充std名称空间,并且有时定义全局符号,而< stdlib.h> 将始终定义全局符号,有时填充std命名空间。这在实施过程中有所不同。

  2. 标准写道: >每个具有名称形式为 name.h 的C标头的行为就如同每个名称放置在标准库名称空间中的相应 cname 头部放置在全局命名空间范围内。 没有指定这些名称是首先在名称空间 std 的名称空间范围(3.3.6)中声明或定义的,然后将其注入到全局命名空间范围由显式使用声明(7.3.3)。

    这意味着编译器允许将这些符号放入全局作用域中并同时 std namespace


  3. 因此,我们发现优先选择一个头文件没有优势。因为它们很可能会污染全球范围



    但是,仍然有必要使用 std 命名空间,当 #include > 时,在<$ c时不要使用 std $ c> #include ,以确保您的代码可以编译所有编译器实现。

  4. 不要在标准库中使用名称。首先,他们不能保证工作。 (注意:当 #include< csomething> 时,很少有编译器实现实际上保持全局作用域是干净的,所以不要依赖这个。)其次,它会混淆代码读取器和维护者,因为几乎每个人都会认为标准名称实际上是标准名称,不管它们来自哪里。


I am using only header files specific to C++ (e.g. <cstdlib>), however I still get globally-declared functions, and not just functions in the std namespace. Is there a way, perhaps a compiler switch, to prevent that?

For example, the following code:

#include <cstdlib>
float random() { return 0.0f; }
int main() { return 0; }

Fails to compile under linux, with the following error:

> g++ -c main.cpp main.o
main.cpp: In function ‘float random()’:
main.cpp:2:14: error: new declaration ‘float random()’
/usr/include/stdlib.h:327:17: error: ambiguates old declaration ‘long int random()’

or

> clang++ main.cpp -o main.o
main.cpp:2:7: error: functions that differ only in their return type cannot be overloaded
float random() { return 0.0f; }
/usr/include/stdlib.h:327:17: note: previous declaration is here
extern long int random (void) __THROW;

which is caused that stdlib.h "pollutes" the global namespace with its own random function.

Note, that I am not facing these problems when compiling on Windows, using Visual Studio.

解决方案

  1. <cstdlib> will always populate std namespace, and sometimes define global symbols, while <stdlib.h> will always define global symbols, and sometimes populate std namespace. This varies from implementation to implementation.

  2. The standard writes:

    Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).

    Which means, that the compiler is allowed to put those symbols into global scope and std namespace at the same time.

  3. Therefore, we see no advantages to prefer one header file over the other. Because they are both very likely to pollute the global scope.

    However, it is still necessary to use std namespace when #include <cstdlib>, and do not use std when #include <stdlib.h>, to make sure your code can compile for all compiler implementations.

  4. Advice: Do not use names in standard libraries. First, they are not guaranteed to work. (Note: Few compiler implementations actually keep the global scope clean when you #include <csomething>, so never depend on this.) Second, it will confuse code readers and maintainers, because almost everyone will assume standard names are actually standard, no matter where they come from.

这篇关于防止std命名空间之外的标准函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆