[parameter] named template parameters

, 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>,
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::_> 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

on Wed Nov 02 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> 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?
Lorenzo, I can't read your code. Could you please try posting it as an inline attachment or something so that it comes out legibly?
, 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>,
#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::_> 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
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Wed, Nov 2, 2011 at 6:24 PM, Dave Abrahams <dave@boostpro.com> wrote:
The following message is a courtesy copy of an article that has been posted to gmane.comp.lib.boost.devel as well.
on Wed Nov 02 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> 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?
Lorenzo, I can't read your code. Could you please try posting it as an inline attachment or something so that it comes out legibly?
Sorry, I'm attaching it as plain text (I don't know why the indentation was all messed up...).
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?
--Lorenzo

On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>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<
::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>,
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::_> > 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

On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>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 :/
OK, let me try again (I tested the formatting of the code below sending an email to myself and it showed up fine): #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 {}; /** @todo to be consistent w/ PARAM_NAME, these macros should generate _ClassType, etc with leading _ be default and in tag namespace by default */ 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; /** @todo use std::auto_ptr instead of boost::shared_ptr */ 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.
Yes but these all sound like implementation reasons to me. If the parameter name keywords need the leading _ for functions, as a library users I'd expect the template parameters to follow the same convention. Why should a user expect template parameter name keywords to follow a different convention than function parameter name keywords?
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 :/
Thanks! --Lorenzo

On Thu, Nov 3, 2011 at 11:05 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com wrote:
[...]
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.
Yes but these all sound like implementation reasons to me. If the parameter name keywords need the leading _ for functions, as a library users I'd expect the template parameters to follow the same convention. Why should a user expect template parameter name keywords to follow a different convention than function parameter name keywords?
Well, they have different syntax as well, i.e., "_keyword = value" vs "keyword< value >" (I guess that's also technically an implementation detail...). My point being, function parameter keyword syntax and template parameter keyword syntax differ, so I don't think it's too onerous for the naming conventions to differ as well. But I see your point, and it probably could've easily gone the other way; honestly, I don't think the argument either way is particularly strong, and by now I'm used to the differing naming convention, so *I* am willing to accept that "this is just the way it is". That's not really suppose to convince *you*, though :) - Jeff

On Thu, Nov 3, 2011 at 11:05 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com 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 :/
OK, let me try again (I tested the formatting of the code below sending an email to myself and it showed up fine):
[...]
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>
[...] This is what I figured you had in mind, and I don't see a problem with it technically. This isn't something I'd encourage for typical use cases, though, as I'd imagine it would make compiler error messages even more unwieldy :) - Jeff

On Thu, Nov 3, 2011 at 2:32 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Thu, Nov 3, 2011 at 11:05 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com 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 :/
OK, let me try again (I tested the formatting of the code below sending an email to myself and it showed up fine):
[...]
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>
[...]
This is what I figured you had in mind, and I don't see a problem with it technically. This isn't something I'd encourage for typical use cases, though, as I'd imagine it would make compiler error messages even more unwieldy :)
I have to decide how Boost.Contract macros are going to expand to support named template parameters. In Boost.Parameter you have to program the code above by hand so you can chose to use extra template parameters (as shown above) or typedefs (as shown in the Boost.Parameter docs) to declare the named parameters ClassType, etc. However, when I make the CONTRACT_CLASS macro expand the Boost.Parameter code then I have to chose one of the approach and stick with it. I'd chose the approach above (extra template params) because it supports using the named template parameters within the class declarations (e.g., base classes) as usual for template parameters unless there is some major drawn back. Also, for symmetry with named function parameters, I will provide Boost.Contract macros that define the template parameter keyword prefixing them with _ by default (_ClassType) and allowing to optionally specify the passing template parameter name (PassClassType) and tag namespace (exactly like the BOOST_PARAMETER_NAME does for named function params) unless there's a real reason for not supporting such symmetry (symmetry that I'd expect in principle as a user). P.S. Boost.Contract named parameters will also strictly enforce that a "in" parameter is passed by const (reference), while "out" and "in out" params are passed by non-const (reference). Thanks. --Lorenzo

On Thu, Nov 3, 2011 at 7:05 PM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Wed, Nov 2, 2011 at 6:46 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>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?
This is similar to what I want to do for the C++11 Boost.Parameter with functions: template < class... Args, class Pack = typename make_pack<parameters, Args...>::type
void f(Args&&... args) { Pack pack(args...); int x = pack[_x]; } In the case of class templates, the downside would be that the error messages would be pretty horrible if the user passes too many arguments. I guess it would be possible to guard a bit against that though, and possibly make the error messages better.
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? [...] Yes but these all sound like implementation reasons to me. If the parameter name keywords need the leading _ for functions, as a library users I'd expect the template parameters to follow the same convention. Why should a user expect template parameter name keywords to follow a different convention than function parameter name keywords?
We simply preferred making the names less ugly over consistency with function parameters.
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?
Nobody implemented it. No real reason not to support it. -- Daniel Wallin BoostPro Computing http://www.boostpro.com

On Mon, Nov 7, 2011 at 5:56 AM, Daniel Wallin <daniel@boostpro.com> wrote:
On Wed, Nov 2, 2011 at 2:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Do you see any problem in using extra template parameter to define the argument pack and named template parameters?
This is similar to what I want to do for the C++11 Boost.Parameter with functions:
template < class... Args, class Pack = typename make_pack<parameters, Args...>::type > void f(Args&&... args) { Pack pack(args...); int x = pack[_x]; }
In the case of class templates, the downside would be that the error messages would be pretty horrible if the user passes too many arguments. I guess it would be possible to guard a bit against that though, and possibly make the error messages better.
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?
We simply preferred making the names less ugly over consistency with function parameters.
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?
Nobody implemented it. No real reason not to support it.
Thanks a lot Daniel! Then I will implement all these features in my integration of Boost.Parameter and Boost.Contract. Also, can you please take a look at why I can't use tag::graph::_ in the DFS example? I really have _no_ idea on how to fix that and I'd need your help... http://boost.2283326.n4.nabble.com/boost-parameter-type-requirement-compiler... For C++11 Boost.Parameter you might want to take a look at what I'll try to do for constructors: https://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html/cont... --Lorenzo

On Mon, Nov 7, 2011 at 6:52 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
For C++11 Boost.Parameter you might want to take a look at what I'll try to do for constructors: https://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html/cont...
Oops, scratch this. For C++11 Boost.Parameter your probably already have better plans leveraging delegating constructors. --Lorenzo
participants (4)
-
Daniel Wallin
-
Dave Abrahams
-
Jeffrey Lee Hellrung, Jr.
-
Lorenzo Caminiti