|
Boost : |
Subject: Re: [boost] [parameter] named template parameters
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-11-02 18:46:51
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti_at_[hidden]>wrote:
> 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?
>
I *think* I know what you're asking, and I *think* it's fine, but I
basically didn't even try parsing the code below due to formatting :/
> #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?
>
The fact that each keyword is used in different contexts is enough
justification for me to explain the asymmetry.
I gathered the leading underscored prepended to function parameter keywords
was motivated by a desire to prevent shadowing bugs (as per the rationale
given in the documentation, if I remember correctly). No such problem
arises with template parameter keywords, so the only justification I can
think of to prepend template parameter keywords with an underscore is
because that's what's done with function parameter keywords, which seems
kind of weak.
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?
>
Not sure; really, I'm not familiar enough with the specifics of the above
macros to be sure that I'm not sure, though :/
- Jeff
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk