clang 的 c++11 支持可靠吗?
Is clang's c++11 support reliable?
我在尝试混合clang(Apple LLVM版本6.0(clang-600.0.56)(基于LLVM 3.5svn,目标:x86_64-apple-darwin14.0.0),c ++ 11和CGAL(通过MacPorts)时遇到了一个有趣的问题。
似乎我是否调用std::vector<>::reserve
将决定我的程序是否会编译。
我已经将问题缩减为一个最小的示例(与 CGAL 示例一样小):
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
// CGAL::Epeck works fine, suggesting the problem is in CGAL::Epick
typedef CGAL::Epick Kernel;
typedef CGAL::Triangle_3<Kernel> Triangle_3;
typedef typename std::vector<Triangle_3>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<Kernel, Iterator> Primitive;
typedef CGAL::AABB_traits<Kernel, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
typedef typename Tree::Point_and_primitive_id Point_and_primitive_id;
typedef CGAL::Point_3<Kernel> Point_3;
template <typename BKernel>
void A()
{
const CGAL::AABB_tree<
CGAL::AABB_traits<BKernel,
CGAL::AABB_triangle_primitive<BKernel,
typename std::vector<CGAL::Triangle_3<BKernel> >::iterator
>
>
> tree;
Point_and_primitive_id pp = tree.closest_point_and_primitive(Point_3());
}
void B()
{
std::vector<Triangle_3> T;
#ifdef MAGIC
T.reserve(0);
#endif
return A<Kernel>();
}
发行:
clang++ -std=c++11 -c example.cpp -I/opt/local/include
这将无法编译。给出错误如下:
In file included from example.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:265:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:626:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/utility:157:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tuple:228:60: error:
no member named 'value' in 'std::__1::is_convertible<const CGAL::Point_3<CGAL::Epick> &,
CGAL::Point_3<CGAL::Epick> >'
is_convertible<_Tp0, _Up0>::value &&
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tuple:242:14: note:
in instantiation of template class 'std::__1::__tuple_convertible_imp<true, std::__1::__tuple_types<const
CGAL::Point_3<CGAL::Epick> &, const CGAL::Vector_3<CGAL::Epick> &>,
std::__1::__tuple_types<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> > >' requested here
: public __tuple_convertible_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
但是,如果我对std::vector::reserve
进行这个神奇的调用,这确实可以编译,发出:
clang++ -std=c++11 -c example.cpp -I/opt/local/include -DMAGIC
或通过禁用 C++11
clang++ -c example.cpp -I/opt/local/include
- 这是 CGAL 中的错误还是叮当声?
- 对于这种不稳定的编译器行为,有什么解释?
- 有没有一种干净的方法来避免这种情况(希望不要真正更改模板或函数原型设置,因为我需要适合我更大项目的解决方案)。
由于Apple的GCC已经过时(2007年最新的GPL v2版本,GCC 4.2.1)并且C++11功能不完整(因此提供了libstdc++),您可以通过MacPorts(sudo port install gcc48
或sudo port install gcc49
)安装更现代的GCC版本,这将为您提供更现代的libstdc++版本。我用以下方法测试了您的代码:
/opt/local/bin/g++-mp-4.8 -std=c++11 -c example.cpp -I/opt/local/include
它编译成功。
如果你更喜欢这个解决方案,并且想要一个更干净的编译器调用;你可以使用命令gcc_select
将MacPorts的GCC设置为默认值(在我的gcc48的情况下):
sudo port select --set gcc mp-gcc48
只有一次。然后,您可以仅使用
g++ -std=c++11 -c example.cpp -I/opt/local/include
在新的终端会话中。
相关文章:
- MSVC是否支持C++11样式的属性而不是__declspec
- 如何检测VS C++编译器是否支持C++11?
- 支持c ++ 11的生成文件
- C++编译器不支持C++11(例如std::unique_ptr)构建OpenWrt
- 支持DirectX 11库的编译器
- GNU C 何时支持C 11,而无需明确要求
- 要使 gcc 4.8.1 支持 c++11 中的新"auto"功能?
- Solaris 上的 GNU gcc/g++ 编译器版本,支持 C++11/14
- 我如何知道我的编译器是否支持XXXXC++11功能
- 编译一个不支持c++11和.cxx文件的cuda代码需要一个带有vexcl示例的c++11
- 支持C++11的开源STL实现
- C++编译器如何支持C++11原子,但不支持C++11内存模型
- Mac 上的 Xcode 工具支持 c++11
- 如何为安卓构建 boost 作为支持 c++11 的共享库
- 带有 g++ 的 CUDA 6.5 不支持 c++11
- 完全支持C++11的Windows C++编译器(应与Qt一起使用)
- Cython 是否支持 C++11 个容器
- 如何检查特定 g++ 版本支持 C++11 的程度
- 编译器标准支持(c++11、c++14、c++17)
- 在G++版本之间切换以支持C++11