8

在 C++0x、C++03 TR1 和 boost 之间,可以根据编译器在 3 个不同的地方定义函数和绑定之类的东西,例如,对于 VC pre VC9 功能包,你有 boost 版本,然后你把它们放进去,但是在 std::tr1:: 命名空间中,VC10 将其移动到 std:: 命名空间。

目前我现有的代码在 boost:: 命名空间中使用旧的 bo​​ost 版本,但是因为对于我的许多应用程序和库,我使用的所有 boost 东西现在都在 tr1 和 C++0x 中,如果可能的话,id 就像删除 boost 依赖从那些,同时保持与旧编译器版本的向后兼容性。

但是我不确定如何让我的代码定位、包含然后能够访问正确的版本:(我考虑过的一件事是使用像 _MSC_VER 这样的宏来查看编译器是否包含我想要的类,(回退到 tr1,然后根据需要进行提升),然后使用“using somenamespace::someclass;”东西将有问题的类移动到 std:: 命名空间中。

问题是似乎在某些情况下这可能会破坏一些东西,我什至不确定如何判断 VC9 是否安装了它的功能包或 SP1 :( ,也许提供我自己的功能性.hpp 来实现所需的“魔法”?

主要的是我想开始为新标准编写代码,但在某种程度上它仍然可以在旧编译器上以最小的努力工作。

4

3 回答 3

8

升压TR1已经为您完成了这项工作——它具有编译器/版本检测逻辑,可以在您的平台可用时使用您的编译器的 TR1 实现,或者如果没有,则使用各种相关的 Boost 库来模拟 TR1:

这个库本身并不实现 TR1 组件,而是一个瘦包装器,将包含您的标准库的 TR1 实现(如果有的话),否则它将包含 Boost Library 等价物,并将它们导入 namespace std::tr1

于 2011-03-02T01:08:08.200 回答
3

从您的帖子看来,您主要关心的是 VC++。如果是这样,那么我认为使用基于 的预处理器定义_MSC_VER可能是最直接的解决方案。正如您所暗示的,只需找出首先提供各种功能并包含适当标题的版本即可。

至于如何在您的代码中访问它们,我将只使用几个typedef设置为不同类型的 s,具体取决于包含的标头。如果库的 boost、tr1 和 C++0x 版本提供相同(或足够相似)的接口,这应该“正常工作”。虽然,如果类型是类模板,普通的 typedef 将不起作用,您将不得不求助于#define。

有时直截了当是好的。可能不值得把它弄得太复杂。(如果你想支持的不仅仅是 VC++,你可能不得不变得复杂。)

也许是这样的(作为第一个想法):

#ifdef _MSC_VER
  #if _MSV_VER >= VERSION_WITH_CXX0X
    #include <function>
    #define FUNCTION_NAMESPACE std
  #elif _MSV_VER >= VERSION_WITH_TR1
    #include <tr1/function>
    #define FUNCTION_NAMESPACE std::tr1
  #else
    #include <boost/function.hpp>
    #define FUNCTION_NAMESPACE boost
#else
  #error The current compiler is not supported.
#endif

void func();

FUNCTION_NAMESPACE::function<void ()> funcobj(func);

尽管我不喜欢使用#define 来获取名称空间,但我想不出另一种方法。不过,我敢打赌有一个。

于 2011-03-02T00:42:45.057 回答
0

由于您已经在使用 Boost,因此请考虑使用Boost.Config 提供的宏来测试可能支持的功能。具体来说,看看BOOST_HAS_TR1_*宏和BOOST_NO_*宏。

请注意,您必须检查各个功能,因为并非所有 TR1 和 C++0x 的实现都支持这些规范的所有功能。

于 2011-03-02T01:01:19.160 回答