[parameter] type requirement compiler error

Hello all, The following parameter type requirement: (required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) ) Generates a GCC error: dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope Detailed code and error below. In fact, if I look at the code after pp, I can see that graph_type is define only after the type requirement is checked... why? What am I doing wrong? Thanks a lot! --Lorenzo #include <boost/graph/adjacency_list.hpp> #include <boost/graph/depth_first_search.hpp> #include <boost/range/irange.hpp> #include <boost/pending/indirect_cmp.hpp> #include <boost/parameter.hpp> #include <iostream> namespace graphs { BOOST_PARAMETER_NAME(graph) BOOST_PARAMETER_NAME(visitor) BOOST_PARAMETER_NAME(root_vertex) BOOST_PARAMETER_NAME(index_map) BOOST_PARAMETER_NAME(color_map) template< typename Size, typename IndexMap > boost::iterator_property_map<boost::default_color_type*, IndexMap, boost::default_color_type, boost::default_color_type&> default_color_map ( Size const& num_vertices, IndexMap const& index_map ) { std::vector<boost::default_color_type> colors(num_vertices); return &colors[0]; } BOOST_PARAMETER_FUNCTION( (void), depth_first_search, tag, (required (graph, *)) (optional (visitor, *, boost::dfs_visitor<>()) (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) (index_map, *, boost::get(boost::vertex_index, graph)) (in_out(color_map), *, default_color_map(boost::num_vertices(graph), index_map)) ) ) { std::cout << "here\n"; boost::depth_first_search(graph, boost::visitor(visitor). color_map(color_map).root_vertex(root_vertex). vertex_index_map(index_map)); } } // namespace graphs template< typename TimeMap > class dfs_time_visitor : public boost::default_dfs_visitor { typedef typename boost::property_traits< TimeMap >::value_type T; public: dfs_time_visitor(TimeMap dmap, TimeMap fmap, T& t) : dmap_(dmap), fmap_(fmap), time_(t) {} template< typename V, typename G > void discover_vertex ( V u, G const& g ) const { put(dmap_, u, time_++); } template< typename V, typename G > void finish_vertex ( V u, G const& g ) const { put(fmap_, u, time_++); } TimeMap dmap_; TimeMap fmap_; T& time_; }; using namespace boost; int main ( ) { typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> G; typedef boost::graph_traits<G>::vertices_size_type size_type; enum {u, v, w, x, y, z, N}; char names[] = {'u', 'v', 'w', 'x', 'y', 'z'}; typedef std::pair<int, int> E; E edges[] = {E(u, v), E(u, x), E(x, v), E(y, x), E(v, y), E(w, y), E(w, z), E(z, z)}; G g(edges, edges + sizeof(edges) / sizeof(E), N); std::vector<size_type> dtime(boost::num_vertices(g)); std::vector<size_type> ftime(boost::num_vertices(g)); size_type t = 0; dfs_time_visitor<size_type*> vis(&dtime[0], &ftime[0], t); graphs::depth_first_search(g, vis); std::vector<size_type> dorder(N); boost::integer_range<size_type> r(0, N); std::copy(r.begin(), r.end(), dorder.begin()); std::sort(dorder.begin(), dorder.end(), boost::indirect_cmp<size_type*, std::less<size_type>
(&dtime[0])); std::cout << "order of discovery: "; for(int i = 0; i < N; ++i) std::cout << names[dorder[i]] << " "; std::cout << std::endl;
std::vector<size_type> forder(N); std::copy(r.begin(), r.end(), forder.begin()); std::sort(forder.begin(), forder.end(), boost::indirect_cmp<size_type*, std::less<size_type>
(&ftime[0])); std::cout << "order of finish: "; for(int i = 0; i < N; ++i) std::cout << names[forder[i]] << " "; std::cout << std::endl;
return 0; } $ g++ -Wall -I../../../../../boost-trunk.cygwin dfs.05.cpp dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope dfs.05.cpp:40: error: template argument 1 is invalid dfs.05.cpp:40: error: expected `::' before ‘,’ token dfs.05.cpp:40: error: expected identifier before ‘,’ token dfs.05.cpp:40: error: template argument 3 is invalid dfs.05.cpp:40: error: expected `::' before ‘{’ token dfs.05.cpp:40: error: expected class-name before ‘{’ token ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp: In instantiation of ‘boost::parameter::aux::argument_pack<graphs::boost_param_params_40depth_first_search<int>, const boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::no_property, boost::no_property, boost::listS>, const dfs_time_visitor<main::size_type*>, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’: dfs.05.cpp:88: instantiated from here ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:157: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_40depth_first_search<int>’ ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:158: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_40depth_first_search<int>’ ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp: In instantiation of ‘boost::parameter::aux::argument_pack<graphs::boost_param_params_40depth_first_search<int>, const boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::no_property, boost::no_property, boost::listS>, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’: dfs.05.cpp:88: instantiated from here ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:157: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_40depth_first_search<int>’ ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:158: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_40depth_first_search<int>’ dfs.05.cpp: In function ‘int main()’: dfs.05.cpp:88: error: no matching function for call to ‘depth_first_search(main()::G&, dfs_time_visitor<size_type*>&)’ -- View this message in context: http://boost.2283326.n4.nabble.com/boost-parameter-type-requirement-compiler... Sent from the Boost - Dev mailing list archive at Nabble.com.

on Mon Oct 24 2011, lcaminiti <lorcaminiti-AT-gmail.com> wrote:
Hello all,
The following parameter type requirement:
(required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) )
Generates a GCC error:
dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope
Yeah.... I'm guessing this is what graphs::graph::_ is all about, but according to revision control, Daniel made this happen, and there's basically no documentation for it. Daniel?
Detailed code and error below.
In fact, if I look at the code after pp, I can see that graph_type is define only after the type requirement is checked... why? What am I doing wrong?
Thanks a lot!
-- Dave Abrahams BoostPro Computing http://www.boostpro.com

Dave Abrahams wrote:
on Mon Oct 24 2011, lcaminiti <lorcaminiti-AT-gmail.com> wrote:
Hello all,
The following parameter type requirement:
(required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) )
Generates a GCC error:
dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope
Yeah.... I'm guessing this is what graphs::graph::_ is all about, but according to revision control, Daniel made this happen, and there's basically no documentation for it. Daniel?
Looking at the code expanded by the macros: namespace graphs { namespace tag { struct graph { static char const* keyword_name() { return "graph"; } typedef boost::parameter::value_type< boost::mpl::_2, graph, boost::parameter::void_ > _; typedef boost::parameter::value_type< boost::mpl::_2, graph, boost::parameter::void_ > _1; }; } namespace { ::boost::parameter::keyword<tag::graph> const& _graph = ::boost::parameter::keyword<tag::graph>::instance; } } So it should be graphs::tag::graph::_ instead of graph_type but I still get the errors: $ g++ -Wall -I../../../../../boost-trunk.cygwin dfs.06.cpp ../../../../../boost-trunk.cygwin/boost/parameter/value_type.hpp: In instantiation of ‘boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’: ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:30: instantiated from ‘boost::graph_traits<boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_> >’ dfs.06.cpp:85: instantiated from here ../../../../../boost-trunk.cygwin/boost/parameter/value_type.hpp:60: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ ../../../../../boost-trunk.cygwin/boost/parameter/value_type.hpp:62: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp: In instantiation of ‘boost::graph_traits<boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_> >’: dfs.06.cpp:85: instantiated from here ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:30: error: no type named ‘vertex_descriptor’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:31: error: no type named ‘edge_descriptor’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:32: error: no type named ‘adjacency_iterator’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:33: error: no type named ‘out_edge_iterator’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:34: error: no type named ‘in_edge_iterator’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:35: error: no type named ‘vertex_iterator’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:36: error: no type named ‘edge_iterator’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:38: error: no type named ‘directed_category’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:39: error: no type named ‘edge_parallel_category’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:40: error: no type named ‘traversal_category’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:42: error: no type named ‘vertices_size_type’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:43: error: no type named ‘edges_size_type’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ ../../../../../boost-trunk.cygwin/boost/graph/graph_traits.hpp:44: error: no type named ‘degree_size_type’ in ‘struct boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’ dfs.06.cpp:85: error: invalid combination of multiple type-specifiers dfs.06.cpp:85: error: expected `::' before ‘,’ token dfs.06.cpp:85: error: expected identifier before ‘,’ token dfs.06.cpp:85: error: template argument 3 is invalid dfs.06.cpp:85: error: expected `::' before ‘{’ token dfs.06.cpp:85: error: expected class-name before ‘{’ token dfs.06.cpp: In function ‘ResultType graphs::boost_param_default_85depth_first_search(ResultType (*)(), const Args&, long int, graph_type&, visitor_type&, boost::parameter::aux::use_default_tag)’: dfs.06.cpp:85: error: invalid combination of multiple type-specifiers dfs.06.cpp:85: error: ‘boost::parameter::aux::cast::remove_const’ is not a type dfs.06.cpp:85: error: invalid combination of multiple type-specifiers dfs.06.cpp:85: error: ‘boost::parameter::aux::cast::execute’ is not a type dfs.06.cpp: In function ‘ResultType graphs::boost_param_default_85depth_first_search(ResultType (*)(), const Args&, int, graph_type&, visitor_type&)’: dfs.06.cpp:85: error: invalid combination of multiple type-specifiers dfs.06.cpp:85: error: ‘boost::parameter::aux::cast::remove_const’ is not a type dfs.06.cpp:85: error: invalid combination of multiple type-specifiers dfs.06.cpp:85: error: ‘boost::parameter::aux::cast::execute’ is not a type ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp: At global scope: ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp: In instantiation of ‘boost::parameter::aux::argument_pack<graphs::boost_param_params_85depth_first_search<int>, const boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::no_property, boost::no_property, boost::listS>, const dfs_time_visitor<main::size_type*>, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’: dfs.06.cpp:132: instantiated from here ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:157: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_85depth_first_search<int>’ ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:158: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_85depth_first_search<int>’ ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp: In instantiation of ‘boost::parameter::aux::argument_pack<graphs::boost_param_params_85depth_first_search<int>, const boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::no_property, boost::no_property, boost::listS>, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’: dfs.06.cpp:132: instantiated from here ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:157: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_85depth_first_search<int>’ ../../../../../boost-trunk.cygwin/boost/parameter/preprocessor.hpp:158: error: no type named ‘parameter_spec0’ in ‘struct graphs::boost_param_params_85depth_first_search<int>’ dfs.06.cpp: In function ‘int main()’: dfs.06.cpp:132: error: no matching function for call to ‘depth_first_search(main()::G&, dfs_time_visitor<size_type*>&)’ I'm lost... (BTW, the examples in documentation mix old and updated syntaxes so they don't quite compile... it'd be nice to update them). Thanks a lot! --Lorenzo -- View this message in context: http://boost.2283326.n4.nabble.com/boost-parameter-type-requirement-compiler... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Mon, Oct 24, 2011 at 2:16 PM, Dave Abrahams <dave@boostpro.com> wrote:
on Mon Oct 24 2011, lcaminiti <lorcaminiti-AT-gmail.com> wrote:
Hello all,
The following parameter type requirement:
(required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) )
Generates a GCC error:
dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope
Yeah.... I'm guessing this is what graphs::graph::_ is all about, but according to revision control, Daniel made this happen, and there's basically no documentation for it. Daniel?
Help anyone?? I'm just trying to compile the graph example from the Boost.Parameter docs, in an ideal world (doc examples added to regression tests) it'd be easier... please help :) --Lorenzo

On Wed, Nov 2, 2011 at 4:40 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Mon, Oct 24, 2011 at 2:16 PM, Dave Abrahams <dave@boostpro.com> wrote:
on Mon Oct 24 2011, lcaminiti <lorcaminiti-AT-gmail.com> wrote:
Hello all,
The following parameter type requirement:
(required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) )
Generates a GCC error:
dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope
Yeah.... I'm guessing this is what graphs::graph::_ is all about, but according to revision control, Daniel made this happen, and there's basically no documentation for it. Daniel?
Help anyone??
I'm just trying to compile the graph example from the Boost.Parameter docs, in an ideal world (doc examples added to regression tests) it'd be easier... please help :)
Here's the deal. If I use tag::graph::_ instead of graph_type, that type is define by the expansion of BOOST_PARAMETER_NAME(graph) as: namespace tag { struct graph { static char const* keyword_name() { return "graph"; } typedef boost::parameter::value_type< boost::mpl::_2, graph, boost::parameter::void_ > _; typedef boost::parameter::value_type< boost::mpl::_2, graph, boost::parameter::void_ > _1; }; } namespace { ::boost::parameter::keyword<tag::graph> const& _graph = ::boost::parameter::keyword<tag::graph>::instance; } Then if I use this type in the declaration of the root_vertex parameter type: (optional (root_vertex, (typename boost::graph_traits<tag::graph::_>::vertex_descriptor), *boost::vertices(graph).first) ) ) I get the error: /usr/include/boost/parameter/value_type.hpp: In instantiation of ‘boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’: /usr/include/boost/graph/graph_traits.hpp:29:52: instantiated from ‘boost::graph_traits<boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_> >’ dfs.06.cpp:85:1: instantiated from here /usr/include/boost/parameter/value_type.hpp:60:13: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ /usr/include/boost/parameter/value_type.hpp:62:5: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ I am not sure but it seems that the mpl::_2 in graph::_ declaration is not bound to anything while it should be bound to Boost.Parameter argument pack... how is this supposed to work? Who should bind mpl::_2 to the argument pack? Thanks a lot. --Lorenzo

I'm sorry for spamming requests for help every day... I'm really stuck here and any help would be very welcome :) Please let me know if I need to clarify my question better. Thanks! On Wed, Nov 2, 2011 at 6:51 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Wed, Nov 2, 2011 at 4:40 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Mon, Oct 24, 2011 at 2:16 PM, Dave Abrahams <dave@boostpro.com> wrote:
on Mon Oct 24 2011, lcaminiti <lorcaminiti-AT-gmail.com> wrote:
Hello all,
The following parameter type requirement:
(required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) )
Generates a GCC error:
dfs.05.cpp:40: error: ‘graph_type’ was not declared in this scope
Yeah.... I'm guessing this is what graphs::graph::_ is all about, but according to revision control, Daniel made this happen, and there's basically no documentation for it. Daniel?
Help anyone??
I'm just trying to compile the graph example from the Boost.Parameter docs, in an ideal world (doc examples added to regression tests) it'd be easier... please help :)
Here's the deal. If I use tag::graph::_ instead of graph_type, that type is define by the expansion of BOOST_PARAMETER_NAME(graph) as:
namespace tag { struct graph { static char const* keyword_name() { return "graph"; } typedef boost::parameter::value_type< boost::mpl::_2, graph, boost::parameter::void_ > _; typedef boost::parameter::value_type< boost::mpl::_2, graph, boost::parameter::void_ > _1; }; } namespace { ::boost::parameter::keyword<tag::graph> const& _graph = ::boost::parameter::keyword<tag::graph>::instance; }
Then if I use this type in the declaration of the root_vertex parameter type:
(optional (root_vertex, (typename boost::graph_traits<tag::graph::_>::vertex_descriptor), *boost::vertices(graph).first) ) )
I get the error:
/usr/include/boost/parameter/value_type.hpp: In instantiation of ‘boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_>’: /usr/include/boost/graph/graph_traits.hpp:29:52: instantiated from ‘boost::graph_traits<boost::parameter::value_type<mpl_::arg<2>, graphs::tag::graph, boost::parameter::void_> >’ dfs.06.cpp:85:1: instantiated from here /usr/include/boost/parameter/value_type.hpp:60:13: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ /usr/include/boost/parameter/value_type.hpp:62:5: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’
I am not sure but it seems that the mpl::_2 in graph::_ declaration is not bound to anything while it should be bound to Boost.Parameter argument pack... how is this supposed to work? Who should bind mpl::_2 to the argument pack?
Thanks a lot. --Lorenzo
--Lorenzo

On Thu, Nov 3, 2011 at 5:04 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
I'm sorry for spamming requests for help every day... I'm really stuck here and any help would be very welcome :) Please let me know if I need to clarify my question better. Thanks!
[...] You might have better luck if you include [graph] in the subject, as (to me) it looks like an issue with Boost.Graph (or...whatever the graph library is called :) In any case, I'm of no help otherwise. - Jeff

On Thu, Nov 3, 2011 at 8:14 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 3, 2011 at 5:04 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
I'm sorry for spamming requests for help every day... I'm really stuck here and any help would be very welcome :) Please let me know if I need to clarify my question better. Thanks!
[...]
You might have better luck if you include [graph] in the subject, as (to me) it looks like an issue with Boost.Graph (or...whatever the graph library is called :)
In any case, I'm of no help otherwise.
Thanks but this question is just on how Boost.Parameter allows to refer to the named parameter type within parameter declaration. It does not involve Boost.Graph at all. The following example raises the same Boost.Parameter error and it uses no graph library: // File: 01.cpp #include <boost/parameter.hpp> #include <iostream> BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y) BOOST_PARAMETER_FUNCTION( (void), f, tag, (required (x, *) (y, (tag::x::_)) ) ) { std::cout << x << " " << y << std::endl; } int main ( void ) { f(1, 2); return 0; } $ g++ -Wall 01.cpp In file included from /usr/include/boost/parameter.hpp:14:0, from 01.cpp:2: /usr/include/boost/parameter/value_type.hpp: In instantiation of ‘boost::parameter::value_type<mpl_::arg<2>, tag::x, boost::parameter::void_>’: 01.cpp:16:1: instantiated from ‘typename boost_param_result_16f<Args>::type boost_param_implf(const Args&) [with Args = boost::parameter::aux::arg_list<boost::parameter::aux::tagged_argument<tag::y, const int>, boost::parameter::aux::arg_list<boost::parameter::aux::tagged_argument<tag::x, const int>, boost::parameter::aux::empty_arg_list> >, typename boost_param_result_16f<Args>::type = void]’ 01.cpp:16:1: instantiated from ‘typename boost_param_result_16f<typename boost::parameter::aux::argument_pack<boost_param_params_16f<int>, const ParameterArgumentType0, const ParameterArgumentType1>::type>::type f(const ParameterArgumentType0&, const ParameterArgumentType1&, typename boost::parameter::aux::match<boost_param_params_16f<int>, ParameterArgumentType0, ParameterArgumentType1>::type) [with ParameterArgumentType0 = int, ParameterArgumentType1 = int, typename boost_param_result_16f<typename boost::parameter::aux::argument_pack<boost_param_params_16f<int>, const ParameterArgumentType0, const ParameterArgumentType1>::type>::type = void, typename boost::parameter::aux::match<boost_param_params_16f<int>, ParameterArgumentType0, ParameterArgumentType1>::type = boost::parameter::parameters<boost::parameter::required<tag::x, boost::mpl::always<mpl_::bool_<true> > >, boost::parameter::required<tag::y, boost::is_convertible<mpl_::arg<-0x000000001>, boost::parameter::value_type<mpl_::arg<2>, tag::x, boost::parameter::void_> > > >]’ 01.cpp:22:11: instantiated from here /usr/include/boost/parameter/value_type.hpp:60:13: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ /usr/include/boost/parameter/value_type.hpp:62:5: error: no type named ‘binding’ in ‘struct mpl_::arg<2>’ 01.cpp: In function ‘typename boost_param_result_16f<Args>::type boost_param_implf(const Args&) [with Args = boost::parameter::aux::arg_list<boost::parameter::aux::tagged_argument<tag::y, const int>, boost::parameter::aux::arg_list<boost::parameter::aux::tagged_argument<tag::x, const int>, boost::parameter::aux::empty_arg_list> >, typename boost_param_result_16f<Args>::type = void]’: 01.cpp:16:1: instantiated from ‘typename boost_param_result_16f<typename boost::parameter::aux::argument_pack<boost_param_params_16f<int>, const ParameterArgumentType0, const ParameterArgumentType1>::type>::type f(const ParameterArgumentType0&, const ParameterArgumentType1&, typename boost::parameter::aux::match<boost_param_params_16f<int>, ParameterArgumentType0, ParameterArgumentType1>::type) [with ParameterArgumentType0 = int, ParameterArgumentType1 = int, typename boost_param_result_16f<typename boost::parameter::aux::argument_pack<boost_param_params_16f<int>, const ParameterArgumentType0, const ParameterArgumentType1>::type>::type = void, typename boost::parameter::aux::match<boost_param_params_16f<int>, ParameterArgumentType0, ParameterArgumentType1>::type = boost::parameter::parameters<boost::parameter::required<tag::x, boost::mpl::always<mpl_::bool_<true> > >, boost::parameter::required<tag::y, boost::is_convertible<mpl_::arg<-0x000000001>, boost::parameter::value_type<mpl_::arg<2>, tag::x, boost::parameter::void_> > > >]’ 01.cpp:22:11: instantiated from here 01.cpp:16:1: error: no matching function for call to ‘boost::parameter::aux::cast<void(boost::parameter::value_type<mpl_::arg<2>, tag::x, boost::parameter::void_>)>::execute(const int&)’ /usr/include/boost/parameter/aux_/cast.hpp:99:28: note: candidates are: static boost::parameter::aux::use_default_tag boost::parameter::aux::cast<void(T)>::execute(boost::parameter::aux::use_default_tag) [with T = boost::parameter::value_type<mpl_::arg<2>, tag::x, boost::parameter::void_>] /usr/include/boost/parameter/aux_/cast.hpp:109:14: note: static T boost::parameter::aux::cast<void(T)>::execute(T) [with T = boost::parameter::value_type<mpl_::arg<2>, tag::x, boost::parameter::void_>] 01.cpp:16:1: error: return-statement with a value, in function returning 'void' --Lorenzo

From: Lorenzo Caminiti
The following example raises the same Boost.Parameter error and it uses no graph library:
// File: 01.cpp #include <boost/parameter.hpp> #include <iostream> BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y) BOOST_PARAMETER_FUNCTION( (void), f, tag, (required (x, *) (y, (tag::x::_)) ) ) { std::cout << x << " " << y << std::endl; } int main ( void ) { f(1, 2); return 0; } Reply: IME you can't use (void) as a return type. As a workaround I use (bool) and return a constant (true or false). HTH, Cromwell D. Enage

On Fri, Nov 4, 2011 at 10:53 PM, Cromwell Enage <sponage@yahoo.com> wrote:
From: Lorenzo Caminiti
The following example raises the same Boost.Parameter error and it uses no graph library:
// File: 01.cpp #include <boost/parameter.hpp> #include <iostream>
BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_FUNCTION( (void), f, tag, (required (x, *) (y, (tag::x::_)) ) ) { std::cout << x << " " << y << std::endl; }
int main ( void ) { f(1, 2); return 0; }
Reply: IME you can't use (void) as a return type. As a workaround I use (bool) and return a constant (true or false).
Thanks but that's not the issue: 1) If you remove the tag::x::_ (e.g., use int for y's type) then it compiles with (void), (bool), and any other result type. 2) If you leave the tag::x::_ as y's type then it does not compile with neither (void), (bool), or any other result type (for all result types you get the same error as above). As far as I understand, the last error about the result type might be induced by the first error which is about mpl::_2 not being bound to a Boost.Parameter argument pack-- who should do that binding? how? Please someone help :) NOTE: I can't implement Boost.Contract support for named parameter without this feature because within the contract macros I need to refer to the parameter types. This is a blocking issue for integrating Boost.Parameter in Boost.Contract!! --Lorenzo

On Sat, Nov 5, 2011 at 7:17 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
Please someone help :)
I looked into Boost.Parameter tests and boost/libs/parameter/test/deduced_dependent_predicate.cpp uses tag::x::_ so I modified the example to the following that compiles: #include <boost/parameter.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/add_pointer.hpp> #include <iostream> BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y) BOOST_PARAMETER_FUNCTION( (int), f, tag, (required (x, *) (y, *(boost::is_same<boost::mpl::_1, tag::x::_>)) ) ) { std::cout << x << " " << y << std::endl; return 0; } int main ( void ) { f(1, 2); return 0; } However, this does not solves the original problem with DFS because the following still does not compile: (root_vertex, // Specified type. *(boost::is_same<boost::mpl::_1, typename boost::graph_traits<tag::graph::_>::vertex_descriptor>), //(2) *boost::vertices(graph).first) You get the same error if you try to manipulate the tag::x::_ type from the example above: #include <boost/parameter.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/add_pointer.hpp> #include <iostream> BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y) BOOST_PARAMETER_FUNCTION( (int), f, tag, (required (x, *) (y, *(boost::is_same<boost::mpl::_, boost::add_pointer<tag::x::_>::type>)) // (2) ) ) { std::cout << x << " " << y << std::endl; return 0; } int main ( void ) { int* p; f(1, p); return 0; } A far as I can tell, there are two major issues here that should be fixed in Boost.Parameter: 1) The docs don't mention tag::xyz::_ at all, they refer to xyx_type which only works within the function definition and not in the function declaration. 2) The change from x_type to tag::xyz::_ broke the ability to manipulate the parameter type in the function declaration. For example, it broke the ability for Boost.Parameter to program the DFS interface. This seems a major feature that was lost and Boost.Parameter should be fixed to regain such a feature. BTW, why was x_type changed to tag::xyx::_? What's the benefit for that? I hope my assessment below is incorrect and someone will be able to tell me how to program (1) and (2) using tag::xyz::_. Thanks. --Lorenzo

On Sun, Nov 6, 2011 at 8:12 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote: On Sat, Nov 5, 2011 at 7:17 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
Please someone help :)
I looked into Boost.Parameter tests and boost/libs/parameter/test/deduced_dependent_predicate.cpp uses tag::x::_ so I modified the example to the following that compiles:
[...]
#include <boost/parameter.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/add_pointer.hpp> #include <iostream>
BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_FUNCTION( (int), f, tag, (required (x, *) (y, *(boost::is_same<boost::mpl::_, boost::add_pointer<tag::x::_>::type>)) // (2)
^^^^^^ Here's the problem in this case: you are eagerly evaluating add_pointer<>. Remove the ::type and this works: (y, *(boost::is_same<boost::mpl::_, boost::add_pointer<tag::x::_> >)) This is really the same problem that the documentation sample has: (required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) ) graph_traits<..> is eagerly evaluated here, resulting in the error. You need to be lazy here, but there's no appropriate metafunction in the graph library, so we need to write one: template <class G> struct vertex_descriptor { typedef typename boost::graph_traits<G>::vertex_descriptor type; }; and then do: (required (graph, *) ) (optional (root_vertex, *(boost::is_convertible<mpl::_, vertex_descriptor<tag::graph::_> >), *boost::vertices(graph).first) ) Note that you need can't use: (vertex_descriptor<tag::graph::_>) because the library doesn't properly treat the predicate as a metafunction in all the places that it should.
A far as I can tell, there are two major issues here that should be fixed in Boost.Parameter: 1) The docs don't mention tag::xyz::_ at all, they refer to xyx_type which only works within the function definition and not in the function declaration.
Yes, clearly a documentation bug.
2) The change from x_type to tag::xyz::_ broke the ability to manipulate the parameter type in the function declaration. For example, it broke the ability for Boost.Parameter to program the DFS interface. This seems a major feature that was lost and Boost.Parameter should be fixed to regain such a feature. BTW, why was x_type changed to tag::xyx::_? What's the benefit for that?
It wasn't changed actually, it always worked like this. Predicates are invoked with two arguments: the argument type to validate, and the partial argument pack containing the preceding function parameters. template <class Arg, class Pack> struct predicate; tag::x::_ is actually a shortcut for: boost::parameter::value_type<tag::x, mpl::_2> intended to simplify referring to preceding parameters in the predicates. Now, if we wanted the ability to access preceding parameter types like in the docs, the macros would need to wrap the user predicates like this: template <class Arg, class Pack> struct z_predicate { typedef typename parameter::value_type<tag::x, Pack> x_type; ... typedef typename parameter::value_type<tag::y, Pack> y_type; typedef typename mpl::apply2<actual-predicate, Arg, Pack>::type type; }; It wasn't done this way for compile time performance reasons. Perhaps we could have done this in a simpler way, where we would build the entire argument pack and then use one single predicate to validate the entire thing once, but that's not how it currently works. Looking at the current docs, it's full of problems like this. :( In fact, *all* of the predicates in the DFS example are wrong. Does this help? -- Daniel Wallin BoostPro Computing http://www.boostpro.com

on Tue Nov 08 2011, Daniel Wallin <daniel-AT-boostpro.com> wrote:
A far as I can tell, there are two major issues here that should be fixed in Boost.Parameter: 1) The docs don't mention tag::xyz::_ at all, they refer to xyx_type which only works within the function definition and not in the function declaration.
Yes, clearly a documentation bug.
Hi Daniel, Could you fix the documentation and run the tests we have set up via LitRE? They passed once upon a time... -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Tue, Nov 8, 2011 at 9:29 AM, Daniel Wallin <daniel@boostpro.com> wrote:
On Sun, Nov 6, 2011 at 8:12 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote: On Sat, Nov 5, 2011 at 7:17 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
Please someone help :)
I looked into Boost.Parameter tests and boost/libs/parameter/test/deduced_dependent_predicate.cpp uses tag::x::_ so I modified the example to the following that compiles:
[...]
#include <boost/parameter.hpp> #include <boost/mpl/placeholders.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/add_pointer.hpp> #include <iostream>
BOOST_PARAMETER_NAME(x) BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_FUNCTION( (int), f, tag, (required (x, *) (y, *(boost::is_same<boost::mpl::_, boost::add_pointer<tag::x::_>::type>)) // (2)
^^^^^^ Here's the problem in this case: you are eagerly evaluating add_pointer<>. Remove the ::type and this works:
(y, *(boost::is_same<boost::mpl::_, boost::add_pointer<tag::x::_> >))
This is really the same problem that the documentation sample has:
(required (graph, *) ) (optional (root_vertex, (typename boost::graph_traits<graph_type>::vertex_descriptor), *boost::vertices(graph).first) )
graph_traits<..> is eagerly evaluated here, resulting in the error. You need to be lazy here, but there's no appropriate metafunction in the graph library, so we need to write one:
template <class G> struct vertex_descriptor { typedef typename boost::graph_traits<G>::vertex_descriptor type; };
and then do:
(required (graph, *) ) (optional (root_vertex, *(boost::is_convertible<mpl::_, vertex_descriptor<tag::graph::_> >), *boost::vertices(graph).first) )
I see. Yes, this worked and I have listed below my original DFS example with this change which now compiles. Thank you very much!
Note that you need can't use:
(vertex_descriptor<tag::graph::_>)
because the library doesn't properly treat the predicate as a metafunction in all the places that it should.
Can this be fixed?
A far as I can tell, there are two major issues here that should be fixed in Boost.Parameter: 1) The docs don't mention tag::xyz::_ at all, they refer to xyx_type which only works within the function definition and not in the function declaration.
Yes, clearly a documentation bug.
Yes, the docs don't mention how to use tag::xyz::_ at all (I even started to look at the source code and I understand some metaprogramming but still I had no clue what was going on). Could the doc examples also be tested by the regression tests to make sure they compile? (I will send another email with attached the source code of all the doc example that I reworked so they compile.)
2) The change from x_type to tag::xyz::_ broke the ability to manipulate the parameter type in the function declaration. For example, it broke the ability for Boost.Parameter to program the DFS interface. This seems a major feature that was lost and Boost.Parameter should be fixed to regain such a feature. BTW, why was x_type changed to tag::xyx::_? What's the benefit for that?
It wasn't changed actually, it always worked like this.
Predicates are invoked with two arguments: the argument type to validate, and the partial argument pack containing the preceding function parameters.
template <class Arg, class Pack> struct predicate;
It'd be great to mention this in the docs as well (I'd probably be able to figure our the issue if I knew this much).
tag::x::_ is actually a shortcut for:
boost::parameter::value_type<tag::x, mpl::_2>
intended to simplify referring to preceding parameters in the predicates.
Now, if we wanted the ability to access preceding parameter types like in the docs, the macros would need to wrap the user predicates like this:
template <class Arg, class Pack> struct z_predicate { typedef typename parameter::value_type<tag::x, Pack> x_type; ... typedef typename parameter::value_type<tag::y, Pack> y_type; typedef typename mpl::apply2<actual-predicate, Arg, Pack>::type type; };
It wasn't done this way for compile time performance reasons. Perhaps we could have done this in a simpler way, where we would build the entire argument pack and then use one single predicate to validate the entire thing once, but that's not how it currently works.
Looking at the current docs, it's full of problems like this. :( In fact, *all* of the predicates in the DFS example are wrong.
Does this help?
Yes, thanks a lot!! This DFS example now compiles :)) #include <boost/graph/adjacency_list.hpp> #include <boost/graph/depth_first_search.hpp> #include <boost/graph/graph_traits.hpp> #include <boost/range/irange.hpp> #include <boost/pending/indirect_cmp.hpp> #include <boost/parameter.hpp> #include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/and.hpp> #include <boost/mpl/placeholders.hpp> #include <iostream> namespace graphs { template< typename G > struct vertex_descriptor { typedef typename boost::graph_traits<G>::vertex_descriptor type; }; template< typename T > struct is_incidence_and_vertex_list_graph : boost::mpl::and_< boost::is_convertible< typename boost::graph_traits<T>::traversal_category , boost::incidence_graph_tag > , boost::is_convertible< typename boost::graph_traits<T>::traversal_category , boost::vertex_list_graph_tag > > {}; template< typename T, typename Key > struct is_property_map_of_key : boost::is_same<Key, typename boost::property_traits<T>::key_type> {}; template< typename T, typename Key > struct is_integral_property_map_of_key : boost::mpl::and_< boost::is_integral<typename boost::property_traits<T>::value_type> , is_property_map_of_key<T, Key> > {}; template< typename Size, typename IndexMap > boost::iterator_property_map<boost::default_color_type*, IndexMap, boost::default_color_type, boost::default_color_type&> default_color_map ( Size const& num_vertices, IndexMap const& index_map ) { std::vector<boost::default_color_type> colors(num_vertices); return &colors[0]; } BOOST_PARAMETER_NAME(graph) BOOST_PARAMETER_NAME(visitor) BOOST_PARAMETER_NAME(root_vertex) BOOST_PARAMETER_NAME(index_map) BOOST_PARAMETER_NAME(color_map) BOOST_PARAMETER_FUNCTION( (void), depth_first_search, tag, (required // Required named parameters (no default value). (graph, *(is_incidence_and_vertex_list_graph<boost::mpl::_>)) ) (optional // Optinal named parameters (with default values). (visitor, *, boost::dfs_visitor<>()) // Any type. (root_vertex, // Specified type. *(boost::is_same< boost::mpl::_, vertex_descriptor<tag::graph::_> >), *boost::vertices(graph).first) (index_map, *(is_integral_property_map_of_key< boost::mpl::_, vertex_descriptor<tag::graph::_> >), boost::get(boost::vertex_index, graph)) (in_out(color_map), *(is_property_map_of_key< boost::mpl::_, vertex_descriptor<tag::graph::_> >), default_color_map(boost::num_vertices(graph), index_map)) ) ) { boost::depth_first_search(graph, boost::visitor(visitor). color_map(color_map).root_vertex(root_vertex). vertex_index_map(index_map)); } } // namespace graphs template< typename TimeMap > class dfs_time_visitor : public boost::default_dfs_visitor { typedef typename boost::property_traits< TimeMap >::value_type T; public: dfs_time_visitor(TimeMap dmap, TimeMap fmap, T& t) : dmap_(dmap), fmap_(fmap), time_(t) {} template< typename V, typename G > void discover_vertex ( V u, G const& g ) const { put(dmap_, u, time_++); } template< typename V, typename G > void finish_vertex ( V u, G const& g ) const { put(fmap_, u, time_++); } TimeMap dmap_; TimeMap fmap_; T& time_; }; int main ( ) { typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> G; typedef boost::graph_traits<G>::vertices_size_type size_type; enum {u, v, w, x, y, z, N}; char names[] = {'u', 'v', 'w', 'x', 'y', 'z'}; typedef std::pair<int, int> E; E edges[] = {E(u, v), E(u, x), E(x, v), E(y, x), E(v, y), E(w, y), E(w, z), E(z, z)}; G g(edges, edges + sizeof(edges) / sizeof(E), N); std::vector<size_type> dtime(boost::num_vertices(g)); std::vector<size_type> ftime(boost::num_vertices(g)); size_type t = 0; dfs_time_visitor<size_type*> vis(&dtime[0], &ftime[0], t); graphs::depth_first_search(g, vis); std::vector<size_type> dorder(N); boost::integer_range<size_type> r(0, N); std::copy(r.begin(), r.end(), dorder.begin()); std::sort(dorder.begin(), dorder.end(), boost::indirect_cmp<size_type*, std::less<size_type> >(&dtime[0])); std::cout << "order of discovery: "; for(int i = 0; i < N; ++i) std::cout << names[dorder[i]] << " "; std::cout << std::endl; std::vector<size_type> forder(N); std::copy(r.begin(), r.end(), forder.begin()); std::sort(forder.begin(), forder.end(), boost::indirect_cmp<size_type*, std::less<size_type> >(&ftime[0])); std::cout << "order of finish: "; for(int i = 0; i < N; ++i) std::cout << names[forder[i]] << " "; std::cout << std::endl; return 0; } --Lorenzo

On Tue, Nov 8, 2011 at 11:21 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Tue, Nov 8, 2011 at 9:29 AM, Daniel Wallin <daniel@boostpro.com> wrote:
On Sun, Nov 6, 2011 at 8:12 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote: I see. Yes, this worked and I have listed below my original DFS example with this change which now compiles. Thank you very much!
Great!
Note that you need can't use:
(vertex_descriptor<tag::graph::_>)
because the library doesn't properly treat the predicate as a metafunction in all the places that it should.
Can this be fixed?
Yes, I commited a fix to trunk in r75415.
A far as I can tell, there are two major issues here that should be fixed in Boost.Parameter: 1) The docs don't mention tag::xyz::_ at all, they refer to xyx_type which only works within the function definition and not in the function declaration.
Yes, clearly a documentation bug.
Yes, the docs don't mention how to use tag::xyz::_ at all (I even started to look at the source code and I understand some metaprogramming but still I had no clue what was going on). Could the doc examples also be tested by the regression tests to make sure they compile? (I will send another email with attached the source code of all the doc example that I reworked so they compile.)
Yep, updated the docs to test this in r75417. -- Daniel Wallin BoostPro Computing http://www.boostpro.com
participants (6)
-
Cromwell Enage
-
Daniel Wallin
-
Dave Abrahams
-
Jeffrey Lee Hellrung, Jr.
-
lcaminiti
-
Lorenzo Caminiti