我有C ++ 03代码,如下所示:
#include <boost/tr1/unordered_map.hpp>
...
std::tr1::unordered_map<std::string, int> mystuff;
...
我开始想知道如果/当我将我的代码转换为C ++ 11时,我会受到影响,而C ++ 11(我猜)没有std::tr1::unordered_map
而是std::unordered_map
。所以我想出了以下黑客:
namespace std
{
using namespace ::std::tr1;
}
...
std::unordered_map<std::string, int> mystuff; // no tr1 now!
...
是否合法(可能禁止将内容导入std
)?是否可以更容易地使用C ++ 11代码进行端口/互操作?
答案 0 :(得分:16)
你不应该触及std
命名空间:即使它现在有效,它也可能导致严重的麻烦(使用新版本的编译器,在不同的编译器上等)。
更新:引用标准(C ++ 2003,第17.4.3.1节“保留名称”)(找到here):
未定义对于C ++程序来说向命名空间std 添加声明或定义或命名空间std中的命名空间,除非另有说明。程序可以将任何标准库模板的模板特化添加到命名空间std。标准库模板的这种特化(完整或部分)会导致未定义的行为,除非声明依赖于用户定义的外部链接类型,除非特化符合原始模板的标准库要求。 [强调我的]
答案 1 :(得分:7)
C ++ 11禁止将内容导入::std
17.6.4.2.1:
如果C ++程序向名称空间
std
或名称空间std
中的名称空间添加声明或定义,则它是未定义的,除非另有说明。
答案 2 :(得分:3)
我认为this question与您的要求非常相似。
特别是,我喜欢这样的答案:“使用autoconf来检测符号可用性,然后使用条件定义来使用给定名称对正确的命名空间进行别名”。
答案 3 :(得分:1)
只有当您有一个证据表明您无法以更清晰的方式支持特定库时,才应尝试这种可移植性,理想情况下,您应该使用特定于该特定环境的#ifdef
来包围它。
tr1
的要点是将std
与tr1
中的内容隔离开来。