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_type
、reference
和 pointer
,但 iterator_category
和 difference_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。
我尝试将 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_type
、reference
和 pointer
,但 iterator_category
和 difference_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。