防止std命名空间之外的标准函数 < >我只使用C++专用的头文件(例如 >,但是我仍然得到全局声明的函数,而不仅仅是代码< STD< /COD>命名空间中的函数。有没有一种方法,也许是编译器开关,来防止这种情况

防止std命名空间之外的标准函数 < >我只使用C++专用的头文件(例如 >,但是我仍然得到全局声明的函数,而不仅仅是代码< STD< /COD>命名空间中的函数。有没有一种方法,也许是编译器开关,来防止这种情况,c++,g++,clang++,C++,G++,Clang++,例如,以下代码: #include <cstdlib> float random() { return 0.0f; } int main() { return 0; } 或 这是由于stdlib.h使用其自己的random函数“污染”全局命名空间造成的 请注意,在Windows上使用Visual Studio进行编译时,我没有遇到这些问题。您可以在自己的名称空间中声明函数,以防止声明冲突 namespace MyFunc { float random() { return 0.0f

例如,以下代码:

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

这是由于
stdlib.h
使用其自己的
random
函数“污染”全局命名空间造成的


请注意,在Windows上使用Visual Studio进行编译时,我没有遇到这些问题。

您可以在自己的名称空间中声明函数,以防止声明冲突

namespace MyFunc
{
float random() { return 0.0f; }
};

通常,我更愿意让函数名与标准的定义不同。
例如,这里可以使用函数名myRandom而不是random,这样我就可以通知稍后维护我的代码的人员,所使用的函数不是定义为标准的函数

该标准明确允许
头将C标准函数的名称带到全局名称空间。

通常,您应该首先避免重新声明。 您可以通过使用名称空间或将源代码拆分为文件(包括
cstdlib
和其他可以使用
static
版本的(名称冲突)函数)来实现这一点

如果这不是一个选项,那么继续阅读。但请注意,以下内容可能非常特定于平台。

通过在我的位置查看我的
cstdlib
stdlib.h
,我注意到有一个开关,
cstdlib
通过它决定它是包含
stdlib.h
还是在
std
命名空间中声明
abort
atext
exit

很明显,您引入了
stdlib.h
分支。进一步查看这个文件,我注意到宏
\uu开始\u名称空间\u STD
和后面的
\uu结束\u名称空间\u STD
。也许您可以使用它,但它(顾名思义)是一些实现内部宏,不应该由您直接设置。然而,由于某些原因,它应该在那里,所以您可能会幸运地搜索到它

经过进一步搜索,发现
random
是未包装到
\uu BEGIN\u NAMESPACE\u STD
中的几个函数(和声明)之一。因此,这不是问题的解决办法。(我发现另一个宏
\u GLIBCPP\u USE\u NAMESPACE
,它似乎在内部也用于
\define\u BEGIN\u NAMESPACE\u STD NAMESPACE STD{

总而言之:这不是一条可行的道路,您应该使用所描述的解决方法之一

  • 将始终填充std命名空间,有时定义全局符号,
    将始终定义全局符号,有时填充std命名空间。这因实现而异

  • 该标准写道:

    每个C头(每个C头都有一个
    name.h
    格式的名称)的行为就好像相应的
    cname
    头放在标准库名称空间中的每个名称都放在全局名称空间范围内一样。未指定这些名称是否首先在名称空间范围内声明或定义(3.3.6)然后通过显式使用声明(7.3.3)将其注入全局命名空间范围

    这意味着,允许编译器同时将这些符号放入全局范围和
    std
    命名空间

  • 因此,我们认为选择一个头文件比选择另一个头文件没有什么好处,因为它们都很可能污染全局范围

    但是,在
    #include
    时仍然需要使用
    std
    命名空间,在
    #include
    时不要使用
    std
    ,以确保您的代码可以针对所有编译器实现进行编译

  • 建议:不要在标准库中使用名称。首先,它们不能保证工作。(注意:当您
    #include
    时,很少有编译器实现能够保持全局范围干净,因此永远不要依赖于此。)其次,它将混淆代码读者和维护者,因为几乎每个人都会认为标准名称实际上是标准的,不管它们来自哪里


  • 我同意,首先将项目保存在单独的名称空间中是一种很好的漫游,也是一种很好的编码实践。但是,我正在使用一个已经存在的代码,尝试从Windows移植到Linux,我不想做太多的更改。虽然宏本身是内部的,但可能存在一些问题“public”编译器开关或其他可以打开它的宏?这也是我的想法,但我还没有找到(我在写答案时开始搜索)。我也不能保证所有内容都能很好地包装到这个名称空间中,但乍一看它看起来很有希望。在我看来,将名称放入全局名称空间会破坏将
    std
    名称空间放在首位的目的。我猜此权限是为了向后兼容。请注意,标准允许,但不要求,因此RE仍然是一个开关,它可以关闭这个。不管是什么原因,标准都会执行它,因此,便携式代码不必与C函数有名称冲突。BTW,C++ 98不允许<代码> <代码>污染全局命名空间,C++引入许可,因为很多实现都难以满足Req。uirement(如果不同时控制C库,这是非常困难或不可能做到的,我似乎记得libstdc++人员的一篇文章描述了这些困难,但我现在找不到)。请注意,
    random
    不是C标准库的一部分。这不是为了
    > 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;
    
    namespace MyFunc
    {
    float random() { return 0.0f; }
    };