在C ++ 0x,C ++ 03 TR1和boost之类的功能和绑定之类的东西可以在3个不同的地方定义,具体取决于编译器,例如对于VC pre VC9功能包,你有boost版本,然后你得到它们位于std :: tr1 :: namespace中,VC10将其移动到std :: namespace。
目前我的现有代码在boost :: namespace中使用了较旧的boost版本,但是因为对于我的许多应用程序和库,我使用的所有增强功能现在都在tr1和C ++ 0x中,如果可能的话就删除id这些提升依赖性,同时保留与旧编译器版本的向后兼容性。
但是我不确定如何使我的代码定位,包含然后能够访问正确的版本:(我考虑的一件事是使用像_MSC_VER这样的宏来查看编译器是否包含我想要的类, (回退到tr1然后根据需要进行提升)然后使用“using somenamespace :: someclass;”来将有问题的类移动到std :: namespace中。
问题是,在某些情况下,这可能会破坏内容,我甚至不确定如何判断VC9是否安装了其功能包或SP1 :(我也不确定是否整齐要做到这一点,或许提供我自己的functional.hpp来完成所需的“魔术”?
主要的是我想开始编写新标准的代码,但是在某种程度上它仍然可以在较旧的编译器上花费很少的工作量。
答案 0 :(得分:8)
Boost。TR1已经为你做了这个 - 它有编译器/版本检测逻辑来使用编译器的TR1实现(如果它可用于你的平台),或者使用各种相关的Boost库来模拟TR1如果没有:
这个库本身并不实现TR1组件,而是一个瘦包装器,它将包含标准库的TR1实现(如果有的话),否则它将包含Boost Library的等价物,并将它们导入到命名空间{{1 }}
答案 1 :(得分:3)
从您的帖子看来,您似乎主要关注VC ++。如果是这样,那么我认为使用基于_MSC_VER
的预处理器定义可能是最直接的解决方案。正如您所暗示的,只需找出哪些版本首先提供各种功能并包含相应的标题。
至于如何在代码中访问它们,我只会根据所包含的标题使用设置为不同类型的几个typedef
。如果库的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来获取命名空间,但我想不出另一种方法。不过我打赌有一个。
答案 2 :(得分:0)
由于您已经在使用Boost,请考虑使用the macros that Boost.Config provides来测试可能支持的功能。具体来说,请查看BOOST_HAS_TR1_*
宏和BOOST_NO_*
宏。
请注意,您必须检查各个功能,因为并非TR1和C ++ 0x的所有实现都支持这些规范的所有功能。