Интеграция cgal C++ в шаблоне python3.6 ошибка

Я пытаюсь интегрировать библиотеку 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.

2 ответа

Решение

Мой оригинальный код, который вы использовали выше, был скомпилирован с использованием Clang, а не gcc. Если вы прочитаете эту статью https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/ вы увидите, что существуют различия в том, как std::iterator_traits реализован для Clang. Кажется, мой код предоставляет достаточно информации о типе для реализации Clang iterator_traits работать, но недостаточно для реализации gcc.

В частности, код для TypedInputIterator определяет value_type, reference а также pointer, но ни iterator_category ни difference_type, Поэтому необходимо добавить два двух отсутствующих определения типа вместе с другими определениями типа в верхней части класса итератора:

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

Это дает полный набор из пяти. Вы также должны включить два заголовка, чтобы сделать эти типы доступными:

#include <iterator>
#include <cstddef>

Отлично, спасибо. Работает. Я еще не знаком с итератором. Я пытался добавить эту строку:

typedef std::ptrdiff_t difference_type;

но я не понял, что мне также нужно добавить iterator_category.

Другие вопросы по тегам