MSVC的内联命名空间模拟(10.0 / 11.0)

时间:2011-10-12 15:30:02

标签: c++ visual-c++ namespaces c++11 inline-namespaces

有没有办法用MSVC模拟inline namespace

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

但有点挫败了目的......

1 个答案:

答案 0 :(得分:8)

我担心这种模仿是不可能的。微软似乎对符号版本控制非常不感兴趣,即使它们在其编译器的每个新版本上打破了标准库上的ABI。 GCC仿真有效,因为强大的使用是内联命名空间功能的基础。 Microsoft从未有类似的事情,因此您无法模拟内联命名空间。我担心你现在不会对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 ++移植到没有rvalue refs的编译器可能无论如何都是无望的。