我有一个Xcode项目,我正在迁移以使用clang的选项-stdlib libc++,以启用C++ 11支持.我的一些源文件需要知道正在使用哪个库,例如我这样做:
#ifdef HAVE_CPP11_LIB_SUPPORT
#include <memory>
#else
#include <tr1/memory>
#endif
#ifdef HAVE_CPP11_LIB_SUPPORT
vector.emplace_back(newValue);
#else
vector.push_back(newValue);
#endif
Run Code Online (Sandbox Code Playgroud)
虽然找到为此选项设置的预处理器宏(如果确实有任何),但我遇到了麻烦.我试过转储clang的输出:
clang -x c++ -std=c++11 -stdlib=libc++ -dM -E - < /dev/null
Run Code Online (Sandbox Code Playgroud)
比较:
clang -x c++ -std=c++11 -stdlib=libstdc++ -dM -E - < /dev/null
Run Code Online (Sandbox Code Playgroud)
但这给出了相同的结果.请注意,我不想打开我们是否使用c ++ 11 语言设置,而是我们是否使用c ++ 11 库.有没有可靠的方法在代码中检测到这一点?
我不知道任何确定的方式可以保证便携,但这是我现在使用的:
// libc++ detected: _LIBCPP_VERSION
// libstdc++ detected: __GLIBCXX__
#if defined(__clang__)
# if __has_include(<__config>) // defines _LIBCPP_VERSION
# include <__config>
# elif __has_include(<bits/c++config.h>) // defines __GLIBCXX__
# include <bits/c++config.h>
# else
# include <ios>
# endif
#elif defined(__GNUC__) // gcc does not have __has_include
# include <ios> // ios should include the c++config.h which defines __GLIBCXX__
#endif
Run Code Online (Sandbox Code Playgroud)
这不是很好,但现在对我有用.
libc ++定义_LIBCPP_VERSION和stdc ++定义__GLIBCXX__哪个好,但不幸的是这些宏没有被编译器定义.相反,它们是在非标准头文件中定义的,除非包含该标头,否则无法测试它们的定义.
注意:显然__GLIBCPP__在旧版本中定义了stdc ++ .由于你需要c ++ 11,这不会成为问题.
Clang有一个很好的功能__has_include,可用于测试这些,但如果没有找到标题,宏回退到只包括一个标准的标题,希望使用引擎盖下的内部标题.我在<ios>这里,但要包含的标准标题的选择取决于您.您可以查找包含内部标题的标题(类似于Linux上的gcc):
grep -Rl '#include <bits/c++config.h>' /usr/include/c++
Run Code Online (Sandbox Code Playgroud)
选择您可能在项目中使用的任何标题.
由于这不能保证适用于任何给定的过去或将来的编译器/标准库版本,我不会依赖这些定义,除了可选功能,如:
#ifdef __GLIBCXX__
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
#endif
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1439 次 |
| 最近记录: |