繁体   English   中英

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
  1. 这是CGAL或clang中的错误吗?
  2. 这种不稳定的编译器行为有什么解释?
  3. 是否有一种清除方式来避免这种情况(希望没有真正改变模板或功能原型设置,因为我需要适合我的大项目的解决方案)。

由于Apple的GCC已经过时(2007年最新的GPL v2版本,GCC 4.2.1)而不是C ++ 11功能完整(因此随附了libstdc ++),您可以通过MacPorts安装更现代版本的GCC( sudo port install gcc48sudo port install gcc49 ),这将为您提供更现代的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

在一个新的终端会议中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM