C++0x / C++11 可用性
截至今天,我知道检测 GCC 是否使用 C++0x/C++11 的唯一方法是检查预定义的宏 __GXX_EXPERIMENTAL_CXX0X__:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
// C++11 code
#else
// C++03 code
#endif
请注意,这可能会在未来发生变化(因此宏的 EXPERIMENTAL 部分)。
编辑:事实上,在@stephan 在评论中指出之前我不知道有更好的方法:
16.8/1 [cpp.predefined]
以下宏名称应由实现定义:
__cplusplus
名称__cplusplus 定义为值201103L 时
编译一个 C++ 翻译单元。157
157) 本标准的未来版本将取代
这个宏的值具有更大的值。不合格的编译器
应该使用最多五个十进制数字的值。
所以我猜你可以这样做:
#if defined(__cplusplus) && (__cplusplus >= 201103L)
但我担心这不适用于标准 C++0x GCC 版本。所以我可能会同时使用__GXX_EXPERIMENTAL_CXX0X__ 和__cplusplus:
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L))
C++0x / C++11 兼容性
然而,仅仅检测是否启用了 C++0x/C++11 支持可能并不总是足够:C++11 支持在整个 GCC 版本中发生了很大变化,不仅在核心语言级别,而且在图书馆级别也是。
我最好的选择是找到您认为可以接受 C++11 支持的最小 GCC 版本,并将上述测试与 GCC 版本测试结合起来,例如:
#if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ >= 5)) // for GCC 4.7+
在boost 和std 之间切换
现在,要在 boost::shared_ptr 和 std::shared_ptr 之间切换有点麻烦,因为 C++03 不支持模板化类型定义。我会在 template struct 中包含所需的定义:
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L))) \
&& (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ >= 5))
template<typename T>
struct my_shared_ptr {
typedef std::shared_ptr<T> type;
// you may also want to forward make_shared etc, this is left as an exercise
};
#else
template<typename T>
struct my_shared_ptr {
typedef boost::shared_ptr<T> type;
// you may also want to forward make_shared etc, this is left as an exercise
};
#endif
my_shared_ptr<int>::type ptr(new int);
编辑:(再次)哎呀,我刚刚注意到 @ComicSansMS 使用简单的非模板 using 指令导入正确的 shared_ptr 的方式。不知道为什么我没有想到这一点。
不过,我仍然坚持我所描述的在 GCC 上检测 C++0x/C++11 的方式。