Boost logo

Boost :

Subject: [boost] [parameter] named template parameters
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-11-02 17:00:57


Hello all (and especially Boost.Parameter's authors),

The Boost.Parameter docs suggest to implement parameter-enabled class
templates using a series of typedes for the argument pack and the
actual argument types. I think it is best to define extra template
parameters with default values to old the argument pack Args and named
template parameters ClassType, etc as shown below. This allows to use
the named template parameters within the class declaration for example
in a base class (boost::python::class_<ClassType, ...>) instead that
just in the class definition.

Do you see any problem in using extra template parameter to define the
argument pack and named template parameters?

#include <boost/parameter.hpp>#include
<boost/python/class.hpp>#include
<boost/type_traits/is_class.hpp>#include
<boost/type_traits/is_base_and_derived.hpp>#include
<boost/mpl/is_sequence.hpp>#include
<boost/mpl/placeholders.hpp>#include <boost/mpl/not.hpp>#include
<boost/mpl/and.hpp>#include <boost/noncopyable.hpp>#include
<boost/shared_ptr.hpp>
namespace py {
namespace detail { struct bases_tag {}; }
template< class B0 = void, class B1 = void, class B2 = void >struct
bases : detail::bases_tag {};
BOOST_PARAMETER_TEMPLATE_KEYWORD(ClassType)
BOOST_PARAMETER_TEMPLATE_KEYWORD(BaseList)BOOST_PARAMETER_TEMPLATE_KEYWORD(HeldType)BOOST_PARAMETER_TEMPLATE_KEYWORD(Copyable)
template<      typename Arg123X0    , typename Arg123X1 =
boost::parameter::void_    , typename Arg123X2 =
boost::parameter::void_    , typename Arg123X3 =
boost::parameter::void_    , typename Args123 = typename
boost::parameter::parameters<        // IF(IS_EMPTY(DEFAULT(p)),
required, optional)          boost::parameter::required<
tag::ClassType            , boost::is_class<boost::mpl::_>          >
      , boost::parameter::optional<            // IF(IS_DEDUCED(p),
deduced<tag::NAME(p)>, tag::NAME(p))
boost::parameter::deduced<tag::BaseList>            //
COMMA_IF(COMPL(IS_EMPTY(REQUIRES(p)))) REQUIRES(p)            ,
boost::is_base_and_derived<detail::bases_tag, boost::mpl::_>
>        , boost::parameter::optional<
boost::parameter::deduced<tag::HeldType>            ,
boost::mpl::not_<                boost::mpl::or_<
boost::is_base_and_derived<detail::bases_tag,
  boost::mpl::_>                    ,
boost::is_same<boost::noncopyable, boost::mpl::_>                >
         >          >        , boost::parameter::optional<
 boost::parameter::deduced<tag::Copyable>            ,
boost::is_same<boost::noncopyable, boost::mpl::_>          >
>::bind<Arg123X0, Arg123X1, Arg123X2, Arg123X3>::type    , typename
ClassType = typename boost::parameter::value_type<            Args123,
tag::ClassType >::type    , typename BaseList = typename
boost::parameter::value_type<            // ...
COMMA_IF(COMPL(IS_EMPTY(DEFAULT(p)))) DEFAULT(p) >::type
Args123, tag::BaseList, bases<> >::type    , typename HeldType =
typename boost::parameter::value_type<            Args123,
tag::HeldType, ClassType >::type    , typename Copyable = typename
boost::parameter::value_type<            Args123, tag::Copyable, void
>::type>struct class_ : boost::python::class_<ClassType, BaseList,
HeldType, Copyable>{    typedef ClassType class_type;    typedef
BaseList base_list;    typedef HeldType held_type;    typedef Copyable
copyable;};
} // namespace py
struct b { virtual ~b() = 0; };
struct d : b { ~d() {} };
// Named parameters.typedef py::class_< py::ClassType<b>,
py::Copyable<boost::noncopyable> > x1;typedef py::class_< d,
py::HeldType< boost::shared_ptr<d> >, py::BaseList< py::bases<b> > >
x2;// Deduced parameters.typedef py::class_< b, boost::noncopyable >
y1;typedef py::class_< d, boost::shared_ptr<d>, py::bases<b> > y2;
A couple more things:
1) I thing that BOOST_PARAMETER_TEMPLATE_KEYWORD(ClassType) macro
should define a symbol _ClassType to be used for the named parameter
so to be consistent with the BOOST_PARAMETER_NAME(x) which defined _x
to be used for the named function parameter. However, ClassType is
defined without the leading _. What is the reason for this asymmetry?
2) I'd expect a macro that allows to specify tag and passing argument
name for template parameters
BOOST_PARAMETER_TEMPLATE_KEYWORD((PassClassType, mytag) ClassType) as
for BOOST_PARAMETER_NAME((pass_x, mytag) x) does for function
parameters. Why is such a usage of BOOST_PARAMETER_TEMPLATE_KEYWORD
not supported?

Thanks a lot.
--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk