我有C++03代码,如下所示:
#include <boost/tr1/unordered_map.hpp>
...
std::tr1::unordered_map<std::string, int> mystuff;
...
我开始怀疑如果我/当我将我的代码转换为 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代码变得更加容易?
你不应该碰std
命名空间:即使它现在有效,以后也会引起严重的头痛(使用新版本的编译器,在不同的编译器上等)。
更新:引用标准(2003 C++,第 17.4.3.1 节"保留名称")(在此处找到):
除非另有说明,否则C++程序未定义将声明或定义添加到命名空间 std 或命名空间 std 中的命名空间。程序可以将任何标准库模板的模板专用化添加到命名空间 std。标准库模板的这种专用化(完全或部分)会导致未定义的行为,除非声明依赖于用户定义的外部链接类型,并且除非专用化满足原始模板的标准库要求。[强调我的]
C++11 17.6.4.2.1 禁止将内容导入::std
:
除非另有指定,否则如果C++程序将声明或定义添加到命名空间
std
或命名空间std
中的命名空间,则未定义程序的行为。
这个问题与您提出的问题非常相似。
特别是,我喜欢答案,它说"使用 autoconf 检测符号可用性,然后使用条件定义为具有给定名称的正确命名空间别名"。
有证据证明你不能以更清晰的方式支持一个特定的库时,才应该尝试这种可移植性,理想情况下,你应该用特定于该特定环境的#ifdef
来包围它。
tr1
的目的是将您的std
与tr1
中的东西隔离开来。