3

有没有办法inline namespace用 MSVC 模拟?

LLVM 的 libc++ 使用它来创建一个隐藏的版本化命名空间,如下所示:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD  } }
#define _VSTD std::_LIBCPP_NAMESPACE
namespace std {
  inline namespace _LIBCPP_NAMESPACE {
  }
}

并在 GCC 上模拟它,如下所示:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD  } }
#define _VSTD std::_LIBCPP_NAMESPACE

namespace std {
namespace _LIBCPP_NAMESPACE {
}
using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
}

现在我的问题是,如何使用 MSVC 实现相同的目标?如果这是不可能的,我会很高兴有一个解决方案,它忽略了版本控制(现在),我猜应​​该是

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
#define _LIBCPP_END_NAMESPACE_STD }
#define _VSTD std

但有点违背了目的......

4

1 回答 1

8

恐怕没有这种仿效的可能。微软似乎对符号版本控制很不感兴趣,即使他们在编译器的每一个新版本中都破坏了标准库中的 ABI。GCC 仿真之所以有效,是因为强使用是内联命名空间功能的基础。微软从来没有类似的东西,所以你不能模拟内联命名空间。恐怕您现在无法对 libc++ 进行版本控制。

Microsoft 的编译器中有一项功能可能会有所帮助。这是#pragma detect_mismatch:http: //msdn.microsoft.com/en-us/library/ee956429.aspx

基本上,你把

#pragma detect_mismatch("libcxx_version", "1.0")

到一个中央 libc++ 头文件中,并且包含该文件的每个模块都将在其中放置一个包含键和值的记录。Microsoft 链接器在链接模块时检查所有此类记录对于任何给定名称是否具有相同的值,并在不匹配时进行投诉。

最终结果是您不能在单个程序中拥有多个并行版本的 libc++,但至少您不会因链接不兼容的目标文件而导致在运行时严重崩溃的静默损坏。

编辑:忘了提:这个功能是 VS2010 中的新功能,但是将 libc++ 移植到没有右值引用的编译器可能还是相当无望的。

于 2011-10-17T14:05:01.463 回答