Mpl for_each with mpl list - c++

I'm trying to use mpl_list in for_each
#include <boost/mpl/list.hpp>
#include <algorithm>
#include <boost/mpl/for_each.hpp>
#include <string>
#include <istream>
#include <ostream>
#include <sstream>
#include <iostream>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/bind.hpp>
using namespace std;
namespace mpl = boost::mpl;
typedef mpl::range_c<char,1,5> range5;
typedef mpl::list<
mpl::int_<1>
, mpl::int_<5>
, mpl::int_<31>
, mpl::int_<14>
, mpl::int_<51>
> inp_type;
typedef mpl::list<
mpl::int_<1>
, mpl::int_<5>
, mpl::int_<31>
, mpl::int_<14>
, mpl::int_<51>
> out_type;
template <class T> struct id {};
struct do_this_wrapper {
static char stat_c ;
typedef void result_type;
template<typename U> inline void operator()(int i, U )
{
if (i == U::value)
{
do_this_wrapper::stat_c = mpl::at_c<out_type,U::value>::type::value;
}
}
};
char do_this_wrapper::stat_c ;
int main()
{
int x;
std::cin>>x;
boost::mpl::for_each<inp_type>(boost::bind(do_this_wrapper(), x, _1));
return do_this_wrapper::stat_c;
};
I've got these errors
*... /usr/include/boost/mpl/list/aux_/iterator.hpp: In instantiation of ‘struct boost::mpl::deref >’: /usr/include/boost/mpl/aux_/at_impl.hpp:37:45: required from ‘struct boost::mpl::at_impl::apply, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> >, mpl_::long_<5l> >’ /usr/include/boost/mpl/at.hpp:42:8: required from ‘struct boost::mpl::at_c, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> >, 5l>’ ../src/TestProj3.cpp:2664:41: required from ‘void do_this_wrapper::operator()(int, U) [with U = mpl_::int_<5>]’ /usr/include/boost/bind/bind.hpp:313:34: required from ‘void boost::_bi::list2::operator()(boost::_bi::type, F&, A&, int) [with F = do_this_wrapper; A = boost::_bi::list1&>; A1 = boost::_bi::value; A2 = boost::arg<1>]’ /usr/include/boost/bind/bind_template.hpp:32:59: required from ‘boost::_bi::bind_t::result_type boost::_bi::bind_t::operator()(A1&) [with A1 = mpl_::int_<5>; R = boost::_bi::unspecified; F = do_this_wrapper; L = boost::_bi::list2, boost::arg<1> >; boost::_bi::bind_t::result_type = void]’ /usr/include/boost/mpl/for_each.hpp:75:25: required from ‘static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::l_iter, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> > >; LastIterator = boost::mpl::l_iter; TransformFunc = boost::mpl::identity; F = boost::_bi::bind_t, boost::arg<1> > >]’ /usr/include/boost/mpl/for_each.hpp:79:111: required from ‘static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::l_iter, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> > >; LastIterator = boost::mpl::l_iter; TransformFunc = boost::mpl::identity; F = boost::_bi::bind_t, boost::arg<1> > >]’ /usr/include/boost/mpl/for_each.hpp:101:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::list, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> >; TransformOp = boost::mpl::identity; F = boost::_bi::bind_t, boost::arg<1> > >]’ /usr/include/boost/mpl/for_each.hpp:111:38: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::list, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> >; F = boost::_bi::bind_t, boost::arg<1> > >]’ ../src/TestProj3.cpp:2678:77: required from here /usr/include/boost/mpl/list/aux_/iterator.hpp:39:33: error: no type named ‘item’ in ‘struct boost::mpl::l_end’ typedef typename Node::item type; ^ /usr/include/boost/mpl/list/aux_/iterator.hpp: In instantiation of ‘struct boost::mpl::next >’: /usr/include/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp:68:44: required from ‘struct boost::mpl::aux::advance_forward<4l>::apply
/usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:36:8:
required from ‘struct boost::mpl::apply_wrap1, boost::mpl::l_iter > > >’ /usr/include/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp:83:21: required from ‘struct boost::mpl::aux::advance_forward<27l>::apply ’ /usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:36:8:
required from ‘struct boost::mpl::apply_wrap1, boost::mpl::l_iter > > >’ /usr/include/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp:92:21: required from ‘struct boost::mpl::aux::advance_forward<31l>::apply, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> > > >’ /usr/include/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:36:8: [ skipping 7 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] /usr/include/boost/bind/bind_template.hpp:32:59: required from ‘boost::_bi::bind_t::result_type boost::_bi::bind_t::operator()(A1&) [with A1 = mpl_::int_<31>; R = boost::_bi::unspecified; F = do_this_wrapper; L = boost::_bi::list2, boost::arg<1> >; boost::_bi::bind_t::result_type = void]’ /usr/include/boost/mpl/for_each.hpp:79:111: recursively required from ‘static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::l_iter, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> > >; LastIterator = boost::mpl::l_iter; TransformFunc = boost::mpl::identity; F = boost::_bi::bind_t, boost::arg<1> > >]’ /usr/include/boost/mpl/for_each.hpp:79:111: required from ‘static void boost::mpl::aux::for_each_impl::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::l_iter, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> > >; LastIterator = boost::mpl::l_iter; TransformFunc = boost::mpl::identity; F = boost::_bi::bind_t, boost::arg<1> > >]’ /usr/include/boost/mpl/for_each.hpp:101:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::list, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> >; TransformOp = boost::mpl::identity; F = boost::_bi::bind_t, boost::arg<1> > >]’ /usr/include/boost/mpl/for_each.hpp:111:38: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::list, mpl_::int_<5>, mpl_::int_<31>, mpl_::int_<14>, mpl_::int_<51> >; F = boost::_bi::bind_t, boost::arg<1> > >]’ ../src/TestProj3.cpp:2678:77: required from here /usr/include/boost/mpl/list/aux_/iterator.hpp:45:43: error: no type named ‘next’ in ‘struct boost::mpl::l_end*’
Would be thankfull for detailed descriprtion or sth to read. Thanks in advance

The issue is
do_this_wrapper::stat_c = mpl::at_c<out_type,U::value>::type::value;
This is asking MPL to find the element at the position in out_type that corresponds to the value of U. Since the inp_type has a value of 51 (among other things), it's failing be able to return the element in position 51 in out_type, since it only contains 5 elements.
Personally, I would attempt to join the two sequences into an associative sequence (mpl::map), and then use for_each over that.

Related

How to precompile CGAL headers to speed up (Ubuntu)

I was launching one of the examples offered by CGAL on their website, and I realized that the compilation time is very high, so I saw that one possibility was to generate a .h file including all the headers that are being used and precompile them.
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/remove_outliers.h>
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/jet_smooth_point_set.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/mst_orient_normals.h>
#include <CGAL/poisson_surface_reconstruction.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/Scale_space_surface_reconstruction_3.h>
#include <CGAL/Scale_space_reconstruction_3/Jet_smoother.h>
#include <CGAL/Scale_space_reconstruction_3/Advancing_front_mesher.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
And after creating the MyHeaders.h I try to compile it using:
g++ -std=c++14 main.cpp -lCGAL -lboost_system -lboost_date_time -lboost_thread -lgmp -lmpfr -L/usr/local/include
But errors of many kinds are coming out. This example, as far as I know, uses CGAL, BOOST, GMP and MPFR.
Does someone know how can I solve this problem? I'm using Ubuntu 20.04 with CGAL 5.4
The errors:
/usr/local/include/CGAL/poisson_surface_reconstruction.h: In instantiation of ‘bool CGAL::poisson_surface_reconstruction_delaunay(PointInputIterator, PointInputIterator, PointMap, NormalMap, PolygonMesh&, double, double, double, double, Tag) [with PointInputIterator = __gnu_cxx::__normal_iterator<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Index*, std::vector<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Index, std::allocator<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Index> > >; PointMap = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >; NormalMap = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Vector_3<CGAL::Epick> >; PolygonMesh = CGAL::Surface_mesh<CGAL::Point_3<CGAL::Epick> >; Tag = CGAL::Manifold_with_boundary_tag]’:
main.cpp:99:38: required from here
/usr/local/include/CGAL/poisson_surface_reconstruction.h:105:10: error: no matching function for call to ‘CGAL::Poisson_reconstruction_function<CGAL::Epick>::compute_implicit_function()’
105 | if ( ! function.compute_implicit_function() )
In file included from /usr/local/include/CGAL/poisson_surface_reconstruction.h:21,
from main.cpp:9:
/usr/local/include/CGAL/Poisson_reconstruction_function.h:417:8: note: candidate: ‘template<class SparseLinearAlgebraTraits_d, class Visitor> bool CGAL::Poisson_reconstruction_function<Gt>::compute_implicit_function(SparseLinearAlgebraTraits_d, Visitor, double, double) [with SparseLinearAlgebraTraits_d = SparseLinearAlgebraTraits_d; Visitor = Visitor; Gt = CGAL::Epick]’
417 | bool compute_implicit_function(
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/CGAL/Poisson_reconstruction_function.h:417:8: note: template argument deduction/substitution failed:
In file included from main.cpp:9:
/usr/local/include/CGAL/poisson_surface_reconstruction.h:105:10: note: candidate expects 4 arguments, 0 provided
105 | if ( ! function.compute_implicit_function() )
In file included from /usr/local/include/CGAL/poisson_surface_reconstruction.h:21,
from main.cpp:9:
/usr/local/include/CGAL/Poisson_reconstruction_function.h:571:8: note: candidate: ‘template<class SparseLinearAlgebraTraits_d> bool CGAL::Poisson_reconstruction_function<Gt>::compute_implicit_function(SparseLinearAlgebraTraits_d, bool) [with SparseLinearAlgebraTraits_d = SparseLinearAlgebraTraits_d; Gt = CGAL::Epick]’
571 | bool compute_implicit_function(SparseLinearAlgebraTraits_d solver, bool smoother_hole_filling = false)
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/CGAL/Poisson_reconstruction_function.h:571:8: note: template argument deduction/substitution failed:
In file included from main.cpp:9:
/usr/local/include/CGAL/poisson_surface_reconstruction.h:105:10: note: candidate expects 2 arguments, 0 provided
105 | if ( ! function.compute_implicit_function() )
In file included from /usr/local/include/CGAL/basic.h:26,
from /usr/local/include/CGAL/Cartesian/Cartesian_base.h:20,
from /usr/local/include/CGAL/Simple_cartesian.h:20,
from /usr/local/include/CGAL/Exact_predicates_inexact_constructions_kernel.h:20,
from main.cpp:1:
/usr/local/include/CGAL/jet_smooth_point_set.h: In instantiation of ‘void CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >; NamedParameters = CGAL::Named_function_parameters<CGAL::Epick, CGAL::internal_np::geom_traits_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Vector_3<CGAL::Epick> >, CGAL::internal_np::normal_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >, CGAL::internal_np::point_t, CGAL::internal_np::No_property> > >]’:
/usr/local/include/CGAL/jet_smooth_point_set.h:285:5: required from ‘void CGAL::jet_smooth_point_set(PointRange&, unsigned int) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >]’
main.cpp:86:65: required from here
/usr/local/include/CGAL/jet_smooth_point_set.h:202:3: error: static assertion failed: Error: no SVD traits
202 | CGAL_static_assertion_msg(!(boost::is_same<SvdTraits,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/CGAL/jet_smooth_point_set.h: In instantiation of ‘void CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Iterator_range<__gnu_cxx::__normal_iterator<CGAL::Point_3<CGAL::Epick>*, std::vector<CGAL::Point_3<CGAL::Epick>, std::allocator<CGAL::Point_3<CGAL::Epick> > > > >; NamedParameters = CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_monge_t, CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_fitting_t, CGAL::internal_np::No_property> >]’:
/usr/local/include/CGAL/Scale_space_reconstruction_3/Jet_smoother.h:83:5: required from ‘void CGAL::Scale_space_reconstruction_3::Jet_smoother<Geom_traits, ConcurrencyTag>::operator()(InputIterator, InputIterator) [with InputIterator = __gnu_cxx::__normal_iterator<CGAL::Point_3<CGAL::Epick>*, std::vector<CGAL::Point_3<CGAL::Epick>, std::allocator<CGAL::Point_3<CGAL::Epick> > > >; Geom_traits = CGAL::Epick; ConcurrencyTag = CGAL::Sequential_tag]’
/usr/local/include/CGAL/Scale_space_surface_reconstruction_3.h:180:39: required from ‘void CGAL::Scale_space_surface_reconstruction_3<Geom_traits>::increase_scale(std::size_t, const Smoother&) [with Smoother = CGAL::Scale_space_reconstruction_3::Jet_smoother<CGAL::Epick>; Geom_traits = CGAL::Epick; std::size_t = long unsigned int]’
main.cpp:136:98: required from here
/usr/local/include/CGAL/jet_smooth_point_set.h:202:3: error: static assertion failed: Error: no SVD traits
In file included from /usr/include/c++/9/functional:59,
from /usr/local/include/CGAL/config.h:431,
from /usr/local/include/CGAL/basic.h:21,
from /usr/local/include/CGAL/Cartesian/Cartesian_base.h:20,
from /usr/local/include/CGAL/Simple_cartesian.h:20,
from /usr/local/include/CGAL/Exact_predicates_inexact_constructions_kernel.h:20,
from main.cpp:1:
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >; NamedParameters = CGAL::Named_function_parameters<CGAL::Epick, CGAL::internal_np::geom_traits_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Vector_3<CGAL::Epick> >, CGAL::internal_np::normal_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >, CGAL::internal_np::point_t, CGAL::internal_np::No_property> > >]::<lambda(const reference&)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = bool; _ArgTypes = {boost::tuples::cons<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Index&, boost::tuples::cons<CGAL::Point_3<CGAL::Epick>&, boost::tuples::null_type> >}]’, declared using local type ‘CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >; NamedParameters = CGAL::Named_function_parameters<CGAL::Epick, CGAL::internal_np::geom_traits_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Vector_3<CGAL::Epick> >, CGAL::internal_np::normal_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >, CGAL::internal_np::point_t, CGAL::internal_np::No_property> > >]::<lambda(const reference&)>’, is used but never defined [-fpermissive]
667 | function<_Res(_ArgTypes...)>::
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >; NamedParameters = CGAL::Named_function_parameters<CGAL::Epick, CGAL::internal_np::geom_traits_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Vector_3<CGAL::Epick> >, CGAL::internal_np::normal_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >, CGAL::internal_np::point_t, CGAL::internal_np::No_property> > >]::<lambda(const reference&)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = bool; _ArgTypes = {boost::tuples::cons<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Index&, boost::tuples::cons<CGAL::Point_3<CGAL::Epick>&, boost::tuples::null_type> >}]’, declared using local type ‘CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >; NamedParameters = CGAL::Named_function_parameters<CGAL::Epick, CGAL::internal_np::geom_traits_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Vector_3<CGAL::Epick> >, CGAL::internal_np::normal_t, CGAL::Named_function_parameters<CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick>, CGAL::Vector_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >, CGAL::internal_np::point_t, CGAL::internal_np::No_property> > >]::<lambda(const reference&)>’, is used but never defined [-fpermissive]
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Iterator_range<__gnu_cxx::__normal_iterator<CGAL::Point_3<CGAL::Epick>*, std::vector<CGAL::Point_3<CGAL::Epick>, std::allocator<CGAL::Point_3<CGAL::Epick> > > > >; NamedParameters = CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_monge_t, CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_fitting_t, CGAL::internal_np::No_property> >]::<lambda(const reference&)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = bool; _ArgTypes = {boost::tuples::cons<CGAL::Point_3<CGAL::Epick>&, boost::tuples::cons<CGAL::Point_3<CGAL::Epick>&, boost::tuples::null_type> >}]’, declared using local type ‘CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Iterator_range<__gnu_cxx::__normal_iterator<CGAL::Point_3<CGAL::Epick>*, std::vector<CGAL::Point_3<CGAL::Epick>, std::allocator<CGAL::Point_3<CGAL::Epick> > > > >; NamedParameters = CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_monge_t, CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_fitting_t, CGAL::internal_np::No_property> >]::<lambda(const reference&)>’, is used but never defined [-fpermissive]
/usr/include/c++/9/bits/std_function.h:667:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Iterator_range<__gnu_cxx::__normal_iterator<CGAL::Point_3<CGAL::Epick>*, std::vector<CGAL::Point_3<CGAL::Epick>, std::allocator<CGAL::Point_3<CGAL::Epick> > > > >; NamedParameters = CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_monge_t, CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_fitting_t, CGAL::internal_np::No_property> >]::<lambda(const reference&)>; <template-parameter-2-2> = void; <template-parameter-2-3> = void; _Res = bool; _ArgTypes = {boost::tuples::cons<CGAL::Point_3<CGAL::Epick>&, boost::tuples::cons<CGAL::Point_3<CGAL::Epick>&, boost::tuples::null_type> >}]’, declared using local type ‘CGAL::jet_smooth_point_set(PointRange&, unsigned int, const NamedParameters&) [with ConcurrencyTag = CGAL::Sequential_tag; PointRange = CGAL::Iterator_range<__gnu_cxx::__normal_iterator<CGAL::Point_3<CGAL::Epick>*, std::vector<CGAL::Point_3<CGAL::Epick>, std::allocator<CGAL::Point_3<CGAL::Epick> > > > >; NamedParameters = CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_monge_t, CGAL::Named_function_parameters<unsigned int, CGAL::internal_np::degree_fitting_t, CGAL::internal_np::No_property> >]::<lambda(const reference&)>’, is used but never defined [-fpermissive]
Edit: Add CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(CGAL_V0)
set(Qt5_DIR "/opt/Qt/5.15.2/gcc_64/lib/cmake/Qt5/")
set(CGAL_DATA_DIR "/usr/include/CGAL")
set(CGAL_DO_NOT_WARN_ABOUT_CMAKE_BUILD_TYPE TRUE)
find_package(CGAL REQUIRED COMPONENTS Core)
find_package(GMP REQUIRED)
message(STATUS "GMP Found: ${GMP_FOUND}")
message(STATUS "GMP Libs: ${GMP_LIBRARIES}")
find_package(MPFR REQUIRED)
message(STATUS "MPFR Found: ${MPFR_FOUND}")
message(STATUS "MPFR Libs: ${MPFR_LIBRARIES}")
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
message(STATUS "Eigen3 Found: ${EIGEN3_FOUND}")
message(STATUS "Eigen3 DIR: ${EIGEN3_INCLUDE_DIR}")
set(CMAKE_CXX_STANDARD 14)
add_executable(CGAL_V0 main.cpp)
target_link_libraries(CGAL_V0 CGAL::CGAL CGAL::CGAL_Core ${MPFR_LIBRARIES} ${GMP_LIBRARIES})

boost.spirit "invalid static_cast" error when trying to count characters with phoenix bind

This code is not my actual code, but just illustrates the issue. I have a rule that matches 0 or more digits, and an action that is supposed to count them and return that count as the synthesized attribute.
The attribute of *qi::ascii::digit should be a std::vector of the matched digits. So, I wrote the action so that it simply calls .size() and assigns the result to the synthesized attribute. To call .size(), I use boost.phoenix to bind a lambda that calls .size().
#include <boost/phoenix/bind/bind_function_object.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <cstdint>
#include <iostream>
#include <string>
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
using It = std::string::iterator;
struct Parser : qi::grammar<std::string::iterator, size_t()> {
Parser() : Parser::base_type(r) {
auto count = [](auto&& v) { return v.size(); };
r %= (*qi::ascii::digit)[qi::_val = phx::bind(count, qi::_1)];
}
qi::rule<It, size_t()> r;
};
int main() {
using namespace std;
std::string s = "123";
int c;
Parser p;
qi::parse(s.begin(), s.end(), p, c);
std::cout << c << '\n';
}
But it doesn't work. I expect this code to compile and print 3. Instead, I get a very long compile error. The error is roughly what I would expect if the action were simply qi::_val = qi::_1, which perplexes me.
In file included from /usr/local/include/boost/type_traits/is_convertible.hpp:20,
from /usr/local/include/boost/type_traits/is_empty.hpp:12,
from /usr/local/include/boost/mpl/empty_base.hpp:23,
from /usr/local/include/boost/fusion/sequence/intrinsic/at.hpp:15,
from /usr/local/include/boost/phoenix/core/expression.hpp:11,
from /usr/local/include/boost/phoenix/bind/bind_function_object.hpp:17,
from spirit2.cpp:1:
/usr/local/include/boost/spirit/home/qi/parse.hpp: In instantiation of ‘bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Expr = int; Attr = Parser]’:
/usr/local/include/boost/spirit/home/qi/parse.hpp:100:25: required from ‘bool boost::spirit::qi::parse(const Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Expr = int; Attr = Parser]’
spirit2.cpp:27:39: required from here
/usr/local/include/boost/spirit/home/qi/parse.hpp:85:9: error: static assertion failed: error_invalid_expression
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/local/include/boost/spirit/home/qi/detail/parse_auto.hpp:14,
from /usr/local/include/boost/spirit/home/qi/auto.hpp:16,
from /usr/local/include/boost/spirit/home/qi.hpp:15,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from spirit2.cpp:4:
/usr/local/include/boost/spirit/home/qi/parse.hpp:88:42: error: request for member ‘parse’ in ‘boost::spirit::compile<boost::spirit::qi::domain, int>((* & expr))’, which is of non-class type ‘boost::spirit::result_of::compile<boost::spirit::qi::domain, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<int>, 0>, boost::spirit::unused_type, void>::type’ {aka ‘int’}
return compile<qi::domain>(expr).parse(first, last, context, unused, attr);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In file included from /usr/local/include/boost/spirit/home/qi/auxiliary/attr.hpp:18,
from /usr/local/include/boost/spirit/home/qi/auxiliary.hpp:19,
from /usr/local/include/boost/spirit/home/qi.hpp:16,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from spirit2.cpp:4:
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp: In instantiation of ‘static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, T, Enable>::call(const T_&, Attribute&, mpl_::false_) [with T_ = std::vector<char, std::allocator<char> >; Attribute = long unsigned int; T = std::vector<char, std::allocator<char> >; Enable = void; mpl_::false_ = mpl_::bool_<false>]’:
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:171:17: required from ‘static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, T, Enable>::call(const T&, Attribute&) [with Attribute = long unsigned int; T = std::vector<char, std::allocator<char> >; Enable = void]’
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:370:63: required from ‘void boost::spirit::traits::detail::assign_to(const T&, Attribute&, mpl_::false_) [with T = std::vector<char, std::allocator<char> >; Attribute = long unsigned int; mpl_::false_ = mpl_::bool_<false>]’
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:393:26: required from ‘void boost::spirit::traits::assign_to(const T&, Attribute&) [with T = std::vector<char, std::allocator<char> >; Attribute = long unsigned int]’
/usr/local/include/boost/spirit/home/qi/detail/attributes.hpp:27:30: required from ‘static void boost::spirit::qi::default_transform_attribute<Exposed, Transformed>::post(Exposed&, const Transformed&) [with Exposed = long unsigned int; Transformed = std::vector<char, std::allocator<char> >]’
/usr/local/include/boost/spirit/home/qi/action/action.hpp:71:36: required from ‘bool boost::spirit::qi::action<Subject, Action>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::unused_type; Attribute = long unsigned int; Subject = boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >; Action = boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >]’
/usr/local/include/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:73:54: [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/boost/function/function_template.hpp:720:7: required from ‘boost::function4<R, T1, T2, T3, T4>::function4(Functor, typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::action<boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> > >, mpl_::bool_<true> >; R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::unused_type&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1068:16: required from ‘boost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::action<boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> > >, mpl_::bool_<true> >; R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::unused_type&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1121:5: required from ‘typename boost::enable_if_<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::action<boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> > >, mpl_::bool_<true> >; R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::unused_type&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&, const boost::spirit::unused_type&)>&]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:185:19: required from ‘static void boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_) [with Auto = mpl_::bool_<true>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> >, 0>&>, 1>&, const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >&>, 2>; Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; T1 = long unsigned int(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:249:31: required from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& boost::spirit::qi::operator%=(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, Expr&&) [with Expr = const boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> >, 0>&>, 1>&, const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >&>, 2>; Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; T1 = long unsigned int(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’
spirit2.cpp:16:69: required from here
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:153:20: error: invalid static_cast from type ‘const std::vector<char, std::allocator<char> >’ to type ‘long unsigned int’
attr = static_cast<Attribute>(val);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
The solution is to drop %:
r = (*qi::ascii::digit)[qi::_val = phx::bind(count, qi::_1)];
The important error message is in the last line: error: invalid static_cast from type ‘const std::vector<char, std::allocator<char> >’ to type ‘long unsigned int’
For why it produces vector<char> see here.
There is use of semantic action and:
r %= p and r = p are equivalent if there are no semantic actions
associated with p.
Read more about it here.
The doqtor did an excellent job of introducing the relevant concepts. I'd just like to show some simplification if you have a recent compiler (which it looks like you do):
phx::function count { [](auto&& v) { return v.size(); } };
r = (*digit)[_val = count(_1)];
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
using It = std::string::const_iterator;
struct Parser : qi::grammar<It, size_t()> {
Parser() : Parser::base_type(r) {
using namespace qi;
phx::function count { [](auto&& v) { return v.size(); } };
r = (*digit)[_val = count(_1)];
}
private:
qi::rule<It, size_t()> r;
};
int main() {
std::string const s = "123";
int c;
Parser p;
if (qi::parse(s.begin(), s.end(), p, c)) {
std::cout << "Number of digits: " << c << "\n";
}
}
Prints
Number of digits: 3

Making FUSION work to display the contents of a structure

The purpose of the following code is to display the contents of a structure. It is based on this answer.
#include <iostream>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/bind.hpp>
struct Node {
int a = 4;
double b = 2.2;
};
BOOST_FUSION_ADAPT_STRUCT(Node, b)
struct print_visitor {
template <class Index, class C> void operator()(Index, C &c) {
std::cout << boost::fusion::extension::struct_member_name<
C, Index::value>::call() << "="
<< boost::fusion::at<Index>(c) << std::endl;
}
};
template <class C> void print_fields(C &c) {
typedef boost::mpl::range_c<
int, 0, boost::fusion::result_of::size<C>::type::value> range;
boost::mpl::for_each<range>(
boost::bind<void>(print_visitor(), _1, boost::ref(c)));
}
int main() {
Node n;
print_fields(n);
}
The compiler (gcc version 4.8.2) complains:
invalid use of incomplete type ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
typedef typename T::type type;
What is the reason and how can I resolve this?
Here is the complete output of the compiler:
-*- mode: compilation; default-directory: "~/SearchLib/AstarWithPolicies/temp/" -*-
Compilation started at Thu Dec 10 11:54:27
make -k
g++ -Wall -Wextra -Werror -std=c++11 -pedantic -I ~/boost_1_59_0 -I /usr/include/cairomm-1.0/ -I /usr/include/cairo/ -I /usr/include/sigc++-2.0/ -I /usr/lib/x86_64-linux-gnu/sigc++-2.0/include/ -I /usr/include/freetype2/ -g -c temp.cpp
In file included from /home/meir/boost_1_59_0/boost/utility/enable_if.hpp:15:0,
from /home/meir/boost_1_59_0/boost/fusion/support/tag_of.hpp:11,
from /home/meir/boost_1_59_0/boost/fusion/support/category_of.hpp:12,
from /home/meir/boost_1_59_0/boost/fusion/adapted/struct/detail/extension.hpp:14,
from /home/meir/boost_1_59_0/boost/fusion/adapted/struct/adapt_struct.hpp:27,
from temp.cpp:7:
/home/meir/boost_1_59_0/boost/core/enable_if.hpp: In instantiation of ‘struct boost::lazy_disable_if_c<false, boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> > >’:
/home/meir/boost_1_59_0/boost/core/enable_if.hpp:70:10: required from ‘struct boost::lazy_disable_if<boost::is_const<Node>, boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> > >’
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: required by substitution of ‘template<class N, class Sequence> constexpr typename boost::lazy_disable_if<boost::is_const<Sequence>, boost::fusion::result_of::at<Sequence, N> >::type boost::fusion::at(Sequence&) [with N = mpl_::integral_c<int, 0>; Sequence = Node]’
temp.cpp:26:48: required from ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34: required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62: required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19: required from here
/home/meir/boost_1_59_0/boost/core/enable_if.hpp:63:30: error: invalid use of incomplete type ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
typedef typename T::type type;
^
In file included from /home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic/begin.hpp:14:0,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/detail/for_each.hpp:11,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/for_each.hpp:12,
from /home/meir/boost_1_59_0/boost/fusion/include/for_each.hpp:11,
from temp.cpp:9:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:53:16: error: declaration of ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
struct at;
^
temp.cpp: In instantiation of ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’:
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34: required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62: required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19: required from here
temp.cpp:26:48: error: no matching function for call to ‘at(Node&)’
<< boost::fusion::at<Index>(c) << std::endl;
^
temp.cpp:26:48: note: candidates are:
In file included from /home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic/begin.hpp:14:0,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/detail/for_each.hpp:11,
from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/for_each.hpp:12,
from /home/meir/boost_1_59_0/boost/fusion/include/for_each.hpp:11,
from temp.cpp:9:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: note: template<class N, class Sequence> constexpr typename boost::lazy_disable_if<boost::is_const<Sequence>, boost::fusion::result_of::at<Sequence, N> >::type boost::fusion::at(Sequence&)
at(Sequence& seq);
^
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: note: substitution of deduced template arguments resulted in errors seen above
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: note: template<class N, class Sequence> constexpr typename boost::fusion::result_of::at<const Sequence, N>::type boost::fusion::at(const Sequence&)
at(Sequence const& seq);
^
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: note: template argument deduction/substitution failed:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp: In substitution of ‘template<class N, class Sequence> constexpr typename boost::fusion::result_of::at<const Sequence, N>::type boost::fusion::at(const Sequence&) [with N = mpl_::integral_c<int, 0>; Sequence = Node]’:
temp.cpp:26:48: required from ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34: required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48: required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62: required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19: required from here
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: error: invalid use of incomplete type ‘struct boost::fusion::result_of::at<const Node, mpl_::integral_c<int, 0> >’
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:53:16: error: declaration of ‘struct boost::fusion::result_of::at<const Node, mpl_::integral_c<int, 0> >’
struct at;
^
make: *** [all] Error 1
Compilation exited abnormally with code 2 at Thu Dec 10 11:54:27
I found this post as I'm practicing the use of the MPL. I got here as I wanted to print the struct_member_name which you were successful at. The short answer is to include <boost/fusion/sequence.hpp>. fusion::at requires a sequence
BOOST_FUSION_ADAPT_STRUCT does only that, it does not create a sequence for the target. If you had have accessed the value in the same way you access the name, it would have worked.
boost::fusion::extension::access::struct_member<C, Index::value>::template apply<C>::call(x)
returns the value of interest. But of course, there is always a better way, that much code is pretty ugly. Once you have a sequence applied to your class, everything gets easier. Now, I didn't find a for_each that iterates and passes types, fusion::for_each dereferences the value and passes that to the functor. So I took some code from boost\fusion\sequence\io\out.hpp which moves across an iterator range.
This example prints the data your way, the iterator way, and directly using fusion's IO. I'm sure I'm missing a whole lot, but this is my first day of actually writing compile time code that works. Thanks for your question, I may not have gotten so far without it!
#include <iostream>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
//https://www.boost.org/doc/libs/1_78_0/libs/fusion/doc/html/fusion/support/deduce_sequence.html
#include <boost/bind/bind.hpp>
#include <boost/fusion/iterator/distance.hpp>
struct test {
int val;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT(test,val,name)
//the origanal with changes
struct print_class
{
template <class Index, typename T>
void operator()(Index, T& x) const
{
std::cout << "from print_class: " << boost::fusion::extension::struct_member_name<T, Index::value>::call()
<< " = " << boost::fusion::at<Index>(x) << std::endl;
}
};
using namespace boost::placeholders;
template <class C> void print_fields(C& c) {
typedef boost::mpl::range_c<
int, 0, boost::fusion::result_of::size<C>::type::value> range;
boost::mpl::for_each<range>(
boost::bind<void>(print_class(), _1, boost::ref(c)));
}
//I could not find anything like this in the fusion namespace, so...
//T is a fusion iterator
namespace boost::fusion {
template <typename T>
auto get_name(){return boost::fusion::extension::struct_member_name<T::seq_type, T::index::value>::call();
}
}
//shamelessly stolen from fusion/io....
namespace {
using namespace boost;
namespace bf = fusion;
struct print_sequence_loop
{
template <typename OS, typename First, typename Last>
static void call(OS&, First&, Last&, mpl::true_)
{
}
template <typename OS, typename First, typename Last>
static void call(OS& os, First& first, Last& last, mpl::false_)
{
bf::result_of::equal_to<
typename bf::result_of::next<First>::type
, Last
>is_last;
//The code that prints
os << bf::get_name<First>() << " = ";
os << *first << std::endl;
//End the code that prints
call(os, fusion::next(first), last, is_last);
}
template <typename OS, typename First, typename Last>
static void call(OS& os, First const& first, Last const& last)
{
bf::result_of::equal_to<First, Last> eq;
call(os, first, last, eq);
}
};
template <typename OS, typename Sequence>
inline void print_sequence(OS& os, Sequence& seq)
{
print_sequence_loop::call(os, fusion::begin(seq), fusion::end(seq));
}
}
using boost::fusion::operators::operator<<;
int main() {
test the_test{ 12,"this is me" };
print_sequence(std::cout, the_test);
std::cout << '\n';
print_fields(the_test);
std::cout << "\n\n this is using fusions OS\n";
std::cout << the_test << std::endl;
}
GCC demo And it works with MSVC.

copying between instances of different variant template classes

Why does one variant assignment compile while the other does not? The template instances do not share any types and char could be converted to int, say. What is boost::variant trying to do, that it cannot do in the case of the first assignment and that it can do in the case of the second assignment? Error is below.
#include <string>
#include "boost/variant.hpp"
int main()
{
boost::variant<char> v1;
boost::variant<std::string, int, double> v2;
v1 = v2; // compile error
v2 = v1; // compiles fine
return 0;
}
In file included from /usr/include/boost/variant.hpp:17:0,
from v.cpp:3:
/usr/include/boost/variant/variant.hpp: In instantiation of 'int boost::variant<T0, TN>::convert_copy_into::internal_visit(T&, int) const [with T = const std::basic_string<char>; T0_ = char; TN = {}]':
/usr/include/boost/variant/detail/visitation_impl.hpp:113:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; typename Visitor::result_type = int; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:156:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int]'
/usr/include/boost/variant/detail/visitation_impl.hpp:237:5: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<3l>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, double, boost::mpl::l_end> > > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2245:13: required from 'static typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T0_ = std::basic_string<char>; TN = {int, double}; typename Visitor::result_type = int]'
/usr/include/boost/variant/variant.hpp:2267:13: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/variant/variant.hpp:1581:13: required from 'void boost::variant<T0, TN>::convert_construct_variant(Variant&) [with Variant = const boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1628:42: required from 'void boost::variant<T0, TN>::convert_construct(const boost::variant<U0, UN ...>&, long int) [with U0 = std::basic_string<char>; UN = {int, double}; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1649:38: required from 'boost::variant<T0, TN>::variant(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2059:29: required from 'void boost::variant<T0, TN>::assign(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2099:19: required from 'boost::variant<T0, TN>& boost::variant<T0, TN>::operator=(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
v.cpp:10:6: required from here
/usr/include/boost/variant/variant.hpp:1366:61: error: no matching function for call to 'boost::variant<char>::initializer::initialize(void* const&, const std::basic_string<char>&)'
return initializer::initialize(storage_, operand);
^
/usr/include/boost/variant/variant.hpp:1366:61: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:32:0,
from /usr/include/boost/variant.hpp:17,
from v.cpp:3:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const char&]
static int initialize(void* dest, param_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param_T {aka const char&}'
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = char&&]
static int initialize(void* dest, param2_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param2_T {aka char&&}'
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: static void boost::detail::variant::initializer_root::initialize()
static void initialize();
^
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: candidate expects 0 arguments, 2 provided
A char definitely can be stored in an int but the converse is not always true. Therefore the one that fails to compile would be unsafe at runtime, so you're probably better off with it failing. Cast the int to a char if you must.

Higher order function « filter » in C++

I wanted to write a higher order function filter with C++. The code I have come up with so far is as follows:
#include <iostream>
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
using namespace std;
bool isOdd(int const i) {
return i % 2 != 0;
}
template <
template <class, class> class Container,
class Predicate,
class Allocator,
class A
>
Container<A, Allocator> filter(Container<A, Allocator> const & container, Predicate const & pred) {
Container<A, Allocator> filtered(container);
container.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());
return filtered;
}
int main() {
int const a[] = {23, 12, 78, 21, 97, 64};
vector<int const> const v(a, a + 6);
vector<int const> const filtered = filter(v, isOdd);
copy(filtered.begin(), filtered.end(), ostream_iterator<int const>(cout, " "));
}
However on compiling this code, I get the following error messages that I am unable to understand and hence get rid of:
/usr/include/c++/4.3/ext/new_allocator.h: In instantiation of ‘__gnu_cxx::new_allocator<const int>’:
/usr/include/c++/4.3/bits/allocator.h:84: instantiated from ‘std::allocator<const int>’
/usr/include/c++/4.3/bits/stl_vector.h:75: instantiated from ‘std::_Vector_base<const int, std::allocator<const int> >’
/usr/include/c++/4.3/bits/stl_vector.h:176: instantiated from ‘std::vector<const int, std::allocator<const int> >’
Filter.cpp:29: instantiated from here
/usr/include/c++/4.3/ext/new_allocator.h:82: error: ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const [with _Tp = const int]’ cannot be overloaded
/usr/include/c++/4.3/ext/new_allocator.h:79: error: with ‘_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const int]’
Filter.cpp: In function ‘Container<A, Allocator> filter(const Container<A, Allocator>&, const Predicate&) [with Container = std::vector, Predicate = bool ()(int), Allocator = std::allocator<const int>, A = const int]’:
Filter.cpp:30: instantiated from here
Filter.cpp:23: error: passing ‘const std::vector<const int, std::allocator<const int> >’ as ‘this’ argument of ‘__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = const int, _Alloc = std::allocator<const int>]’ discards qualifiers
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >, _Predicate = bool (*)(int)]’:
Filter.cpp:23: instantiated from ‘Container<A, Allocator> filter(const Container<A, Allocator>&, const Predicate&) [with Container = std::vector, Predicate = bool ()(int), Allocator = std::allocator<const int>, A = const int]’
Filter.cpp:30: instantiated from here
/usr/include/c++/4.3/bits/stl_algo.h:821: error: assignment of read-only location ‘__result.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = const int*, _Container = std::vector<const int, std::allocator<const int> >]()’
/usr/include/c++/4.3/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::deallocate(_Tp*, size_t) [with _Tp = const int]’:
/usr/include/c++/4.3/bits/stl_vector.h:150: instantiated from ‘void std::_Vector_base<_Tp, _Alloc>::_M_deallocate(_Tp*, size_t) [with _Tp = const int, _Alloc = std::allocator<const int>]’
/usr/include/c++/4.3/bits/stl_vector.h:136: instantiated from ‘std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = const int, _Alloc = std::allocator<const int>]’
/usr/include/c++/4.3/bits/stl_vector.h:286: instantiated from ‘std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = const int*, _Tp = const int, _Alloc = std::allocator<const int>]’
Filter.cpp:29: instantiated from here
/usr/include/c++/4.3/ext/new_allocator.h:98: error: invalid conversion from ‘const void*’ to ‘void*’
/usr/include/c++/4.3/ext/new_allocator.h:98: error: initializing argument 1 of ‘void operator delete(void*)’
/usr/include/c++/4.3/bits/stl_algobase.h: In function ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false, _II = const int*, _OI = const int*]’:
/usr/include/c++/4.3/bits/stl_algobase.h:435: instantiated from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false, _II = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >, _OI = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >]’
/usr/include/c++/4.3/bits/stl_algobase.h:466: instantiated from ‘_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >, _OI = __gnu_cxx::__normal_iterator<const int*, std::vector<const int, std::allocator<const int> > >]’
/usr/include/c++/4.3/bits/vector.tcc:136: instantiated from ‘__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = const int, _Alloc = std::allocator<const int>]’
Filter.cpp:23: instantiated from ‘Container<A, Allocator> filter(const Container<A, Allocator>&, const Predicate&) [with Container = std::vector, Predicate = bool ()(int), Allocator = std::allocator<const int>, A = const int]’
Filter.cpp:30: instantiated from here
/usr/include/c++/4.3/bits/stl_algobase.h:396: error: no matching function for call to ‘std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m(const int*&, const int*&, const int*&)’
Please tell me what I am doing wrong here and what is the correct way to achieve the kind of higher order polymorphism I want.
Thanks.
EDIT:
Thank you, everyone. Here's the new code I got after applying your suggestions (and it works now, yay!)
#include <iostream>
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
using namespace std;
bool isOdd(int const i) {
return i % 2 != 0;
}
template <
template <typename, typename> class Container,
typename Predicate,
typename Allocator,
typename A
>
Container<A, Allocator> filter(Container<A, Allocator> const & container, Predicate const & pred) {
Container<A, Allocator> filtered(container);
filtered.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());
return filtered;
}
int main() {
int a[] = {23, 12, 78, 21, 97, 64};
vector<int> v(a, a + 6);
vector<int> filtered = filter(v, isOdd);
copy(filtered.begin(), filtered.end(), ostream_iterator<int>(cout, " "));
}
Why is your Container parametrized at all?
template <typename C, typename P>
C filter(C const & container, P pred) {
C filtered(container);
filtered.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());
return filtered;
}
Works just as well. Notice that I passed P by value rather than by const reference, as advised by Meyers in Effective C++ (iterators and functors should be passed by value).
what about remove_copy_if instead ? (with isEven()). It's already built for you.
The error is not in filter, but in:
int main() {
int const a[] = {23, 12, 78, 21, 97, 64};
vector<int const> const v(a, a + 6);
}
You can't have a vector of const stuff. Remove the inner const:
int main() {
int const a[] = {23, 12, 78, 21, 97, 64};
vector<int> const v(a, a + 6);
}
(And of course, filtered.erase, not container.erase.)
container is a const-reference. You can't call erase() on it. You probably mean to call
filtered.erase(remove_if(filtered.begin(), filtered.end(), pred), filtered.end());