python3.6 模板错误中的 cgal C++ 集成

cgal c++ integration in python3.6 template error

我尝试将 cgal 库集成到我的 python 程序中。我按照不同的教程做了一些测试。我尝试做一个模板,但在编译时出现错误,我不知道如何修复它。我使用 pybind11 来集成 cgal。

我的部分 mesher.cpp 代码:

template <typename T>
class TypedInputIterator
{
public:
    typedef T value_type;
    typedef T& reference;
    typedef T* pointer;

    explicit TypedInputIterator(py::iterator& py_iter):
            py_iter_(py_iter){}

    explicit TypedInputIterator(py::iterator&& py_iter):
            py_iter_(py_iter){}

    value_type operator*(){
        return (*py_iter_).template cast<value_type>();
    }

    TypedInputIterator operator++(int){
        auto copy = *this;
        ++py_iter_;
        return copy;
    }

    TypedInputIterator& operator++(){
        ++py_iter_;
        return *this;
    }

    bool operator != (TypedInputIterator &rhs) {
        return py_iter_ != rhs.py_iter_;
    }

    bool operator == (TypedInputIterator &rhs) {
        return py_iter_ == rhs.py_iter_;
    }

private:
    py::iterator py_iter_;
};

PYBIND11_MODULE(cgal_mesher, m)
{

    py::class_<Point>(m, "Point")
                    .def(py::init<int,int>(), py::arg("x"), py::arg("y"))
                    .def(py::init<double,double>(), py::arg("x"), py::arg("y"))
                    .def_property_readonly("x", &Point::x)
                    .def_property_readonly("y", &Point::y)
                    .def("__repr__",
                         [](const Point &p){
                            std::string r("Point(");
                            r += boost::lexical_cast<std::string>(p.x());
                            r += ", ";
                            r += boost::lexical_cast<std::string>(p.y());
                            r +=")";
                            return r;
                         })
                    .def("__hash__",
                         [](const Point &p){
                            std::hash<double> double_hash;
                            auto x_hash = double_hash(p.x());
                            auto y_hash = double_hash(p.y());
                            return y_hash ^ x_hash + 0x9e1779b9 + (y_hash << 6) + (y_hash >> 2);
                         })
                    .def("__eq__",
                         [](const Point &p, const Point & q) {
                            return p == q;
                         })
                    ;

    py::class_<Mesher>(m, "Mesher")
                    .def(py::init<CDT&>())
                    .def("seeds_from", [](Mesher & mesher, py::iterable iterable)
                    {
                        py::iterator iterator = py::iter(iterable);
                        TypedInputIterator<Point> points_begin(iterator);
                        TypedInputIterator<Point> points_end(py::iterator::sentinel());
                        mesher.set_seeds(points_begin, points_end);
                    })

                    ;
}

我知道错误附加到这一行:

mesher.set_seeds(points_begin, points_end);

因为我评论的时候,已经没有错误信息了。

错误信息:

[ 50%] Building CXX object CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o /usr/bin/c++  
-DCGAL_USE_CORE=1 -DCGAL_USE_GMP -DCGAL_USE_MPFR -Dcgal_mesher_EXPORTS -isystem /home/admin-suz/anaconda3/include -I/home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/build/temp.linux-x86_64-3.6
-isystem /usr/local/include -I/home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher
-I/home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include
-I/home/admin-suz/anaconda3/include/python3.6m  -DVERSION_INFO=\"0.1\"  -O3 -DNDEBUG -fPIC -fvisibility=hidden   -std=c++14 -flto -fno-fat-lto-objects -frounding-math -o CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o -c /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher/cgal_mesher.cpp In file included from /usr/include/c++/5/bits/forward_list.h:38:0,
                 from /usr/include/c++/5/forward_list:38,
                 from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/detail/common.h:140,
                 from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/pytypes.h:12,
                 from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/cast.h:13,
                 from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/attr.h:13,
                 from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/pybind11.h:43,
                 from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher/cgal_mesher.cpp:1: /usr/include/c++/5/bits/stl_algobase.h: In instantiation of ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; _OI = std::back_insert_iterator<std::__cxx11::list<CGAL::Point_2<CGAL::Epick>, std::allocator<CGAL::Point_2<CGAL::Epick> > > >]’: /usr/include/c++/5/bits/stl_algobase.h:438:45:   required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; _OI = std::back_insert_iterator<std::__cxx11::list<CGAL::Point_2<CGAL::Epick>, std::allocator<CGAL::Point_2<CGAL::Epick> > > >]’ /usr/include/c++/5/bits/stl_algobase.h:471:8:   required from ‘_OI std::copy(_II, _II, _OI) [with _II = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; _OI = std::back_insert_iterator<std::__cxx11::list<CGAL::Point_2<CGAL::Epick>, std::allocator<CGAL::Point_2<CGAL::Epick> > > >]’ /usr/local/include/CGAL/Delaunay_mesher_2.h:137:14:   required from ‘void CGAL::Delaunay_mesher_2<Tr, Crit>::set_seeds(InputIterator, InputIterator, bool, bool) [with InputIterator = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; Tr = CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Delaunay_mesh_vertex_base_2<CGAL::Epick>, CGAL::Delaunay_mesh_face_base_2<CGAL::Epick> > >; Crit = CGAL::Delaunay_mesh_size_criteria_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Delaunay_mesh_vertex_base_2<CGAL::Epick>, CGAL::Delaunay_mesh_face_base_2<CGAL::Epick> > > >]’ /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher/cgal_mesher.cpp:169:66: required from here /usr/include/c++/5/bits/stl_algobase.h:393:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
       typedef typename iterator_traits<_II>::value_type _ValueTypeI;
                                                         ^ /usr/include/c++/5/bits/stl_algobase.h:395:64: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
       typedef typename iterator_traits<_II>::iterator_category _Category;
                                                                ^ /usr/include/c++/5/bits/stl_algobase.h:399:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
         && __are_same<_ValueTypeI, _ValueTypeO>::__value);
         ^ /usr/include/c++/5/bits/stl_algobase.h:402:44: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
                        _Category>::__copy_m(__first, __last, __result);
                                            ^ CMakeFiles/cgal_mesher.dir/build.make:65 : la recette pour la cible « CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o » a échouée make[2]: *** [CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o] Erreur 1 make[2] : on quitte le répertoire « /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/build/temp.linux-x86_64-3.6 » CMakeFiles/Makefile2:70 : la recette pour la cible « CMakeFiles/cgal_mesher.dir/all » a échouée make[1]: *** [CMakeFiles/cgal_mesher.dir/all] Erreur 2 make[1] : on quitte le répertoire « /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/build/temp.linux-x86_64-3.6 » Makefile:97 : la recette pour la cible « all » a échouée

感谢您的帮助。

我正在使用 ubuntu 16.4 和 python 3.6。

我的 original code which you've used, above, was compiled with Clang rather than gcc. If you read this article https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/ 您会看到 std::iterator_traits 为 Clang 实现的方式存在差异。看来我的代码为 iterator_traits 的 Clang 实现提供了足够的类型信息,但对于 gcc 实现来说还不够。

特别是,TypedInputIterator 的代码定义了 value_typereferencepointer,但 iterator_categorydifference_type 都没有定义。因此,两个缺少的 typedef 需要添加到迭代器顶部附近的其他 typedef class:

typedef std::input_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;

这给出了全套五个。您还应该包括两个 headers 以使这些类型可用:

#include <iterator>
#include <cstddef>

太好了,谢谢。它的工作。我还不熟悉迭代器。我试图添加这一行:

typedef std::ptrdiff_t difference_type;

但我不明白我还必须添加 iterator_category。