我认为这是在编译LLVM/Clang时出现命名空间“std”中没有类型名称“unique_ptr”的一部分问题的原因。根据Marshall Clow的说法,我可以通过_LIBCPP_VERSION
检测-stdlib=libc++
:
如果你在编写跨平台代码,有时需要知道你正在使用哪个标准库。理论上,它们应该都提供相同的功能,但这只是理论。有时您只需要知道。检查libc++的最佳方法是查找预处理器符号_LIBCPP_VERSION。如果定义了该符号,则说明您正在使用libc++。
#ifdef _LIBCPP_VERSION
// libc++ specific code here
#else
// generic code here
#endif
很不幸,这在苹果的Clang(3.4-SVN)和我从LLVM项目下载并编译的源代码中构建的Clang(3.6)上都无法正常工作。我猜测这个测试只在Xcode下有效。如何可靠地在预处理器中检测
-stdlib=libc++
?
以下是测试案例:
$ cat test-clapple.cxx
// Need to test {C++03,C++11} x {libc++, no libc++}
// c++ -c test-clapple.cxx
// - OK
// c++ -stdlib=libc++ -c test-clapple.cxx
// - OK
// c++ -std=c++11 -c test-clapple.cxx
// - FAILS, no type named 'unique_ptr' in namespace 'std'
// c++ -std=c++11 -stdlib=libc++ -c test-clapple.cxx
// - OK
#include <ciso646>
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600)
# pragma message "C++11"
#elif (__cplusplus >= 199711L)
# pragma message "C++03"
#endif
#if (_LIBCPP_VERSION)
# pragma message "libc++"
#else
# pragma message "no libc++"
#endif
#if defined(__apple_build_version__)
# pragma message "Apple build"
#else
# pragma message "non-Apple build"
#endif
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600) // C++11
# include <memory>
#else
# include <tr1/memory>
#endif
// Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1600)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif // C++11
int main(int argc, char* argv[])
{
return argc;
}
这个项目不使用Autotools、Cmake、Boost或其他外部库或框架。
_LIBCPP
,但更有可能是由libc++自己设置的,不是吗? - Lightness Races in Orbit_LIBCPP_VERSION
是正确的检查方式,但在其被定义之前,您必须实际上先包含一个标准库头文件。 - Jonathan Wakely