[Parameter] Constructors and more
Hi, I've just started playing around with Boost.Parameter. I'm in the progress of wrapping a legacy C library and some of the structs used have plenty of members, most of which have reasonable defaults. I thought that the Parameter library would be a nice fit here, but ended up with a couple of questions: 1. How can I define constructor for a class taking named parameters, without using the double parentheses syntax? The following basic idea works, but is ugly: --- ... BOOST_PARAMETER_KEYWORD(tag, minVal) BOOST_PARAMETER_KEYWORD(tag, maxVal) struct Foo { template<typename ArgPack> Foo(ArgPack& args) { m_minVal = args[minVal|0]; m_maxVal = args[maxVal|100]; } ... }; void bar() { Foo foo(( minVal = 1, maxVal = 2)); // Note double parens } --- I've experimented some with defining a parameter::parameters specification and use (the undocumented) BOOST_PARAMETER_MEMFUN, but that obviously doesn't work (forwarding, return values and constructors don't mix). It should be possible (I think) to define a BOOST_PARAMETER_CTOR macro that generate the ctor overloads and forwards to a setter method instead of the other way around. I guess I could create a free or static member function that constructs an object, but that would either force me to create heap-based objects, or invoke potentially expensive copy ctors. 2. Is there a way of detecting whether an argument was passed using position or name? Or, even better, is there a way of restricting the arguments to only be passed by name using the parameters specification? 3. Not a question really, but having a default arity of 5 seems awfully low to me. I hit that limit on first usage, and as the named parameters are supposed to be used in the interface of my wrapping library, forcing users to define BOOST_PARAMETER_MAX_ARITY "globally" feels a bit like asking for someone coming up and asking me to decode some compile errors. [I'm using the latest cvs head of boost, in combination with VC 8.0] Regards, Johan Nilsson
"Johan Nilsson"
I've experimented some with defining a parameter::parameters specification and use (the undocumented) BOOST_PARAMETER_MEMFUN, but that obviously doesn't work (forwarding, return values and constructors don't mix).
Generally you have to forward the overloaded constructors to a base class constructor that takes the ArgumentPack and does all the "real" work. IOW, you may need to insert a base class in the hierarchy just for the purpose of construction.
It should be possible (I think) to define a BOOST_PARAMETER_CTOR macro that generate the ctor overloads and forwards to a setter method instead of the other way around.
It won't be general enough to initialize constant or reference members.
2. Is there a way of detecting whether an argument was passed using position or name?
Nope.
Or, even better, is there a way of restricting the arguments to only be passed by name using the parameters specification?
Nope. Why do you want to do that?
3. Not a question really, but having a default arity of 5 seems awfully low to me. I hit that limit on first usage, and as the named parameters are supposed to be used in the interface of my wrapping library, forcing users to define BOOST_PARAMETER_MAX_ARITY "globally" feels a bit like asking for someone coming up and asking me to decode some compile errors.
Reasonable point. Daniel, what do you think? -- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams wrote:
"Johan Nilsson"
writes:
[snip]
It should be possible (I think) to define a BOOST_PARAMETER_CTOR macro that generate the ctor overloads and forwards to a setter method instead of the other way around.
It won't be general enough to initialize constant or reference members.
That's true, but for my current purposes it's good enough. I've defined my own <foo>_PARAMETER_CTOR macro which takes care of it by delegation. Ideally a BOOST_PARAMETER_CTOR macro should handle initialization of const and reference members automagically, but if restrictions were stated clearly in the docs I'd find an imperfect inclusion better than no one at all. I personally very rarely use constant/reference class members, but understand your concerns. Perhaps a BOOST_PARAMETER_RESTRICTED_CTOR (or similarly ugly-named) macro could be included in the library? Otherwise, maybe mentioning something about constructors in the faq would be a good idea? Also, should the BOOST_PARAMETER_MEMFUN macro be documented?
2. Is there a way of detecting whether an argument was passed using position or name?
Nope.
Ok.
Or, even better, is there a way of restricting the arguments to only be passed by name using the parameters specification?
Nope. Why do you want to do that?
I'd like to make sure that users have absolutely (well, almost) no
possibility of using arguments incorrectly. Consider the following (does not
compile):
---
#include
{}; BOOST_PARAMETER_FUN(int, wrap_foo, 0, 4, wrap_foo_args) { return foo(p[index_p|-1], p[low_limit_p|0], p[high_limit_p|255], p[buffer_size_p|1]); } int foo_with_fixed_high_and_buffer_size(int ndx, int low) { return wrap_foo(low, ndx, high_limit_p = 1, buffer_size_p = 10); // ouch ... } --- [snip remaining] // Johan
"Johan Nilsson"
David Abrahams wrote:
"Johan Nilsson"
writes: [snip]
It should be possible (I think) to define a BOOST_PARAMETER_CTOR macro that generate the ctor overloads and forwards to a setter method instead of the other way around.
It won't be general enough to initialize constant or reference members.
That's true, but for my current purposes it's good enough. I've defined my own <foo>_PARAMETER_CTOR macro which takes care of it by delegation.
Ideally a BOOST_PARAMETER_CTOR macro should handle initialization of const and reference members automagically, but if restrictions were stated clearly in the docs I'd find an imperfect inclusion better than no one at all.
If you propose a patch against the current CVS, we'll consider it for boost 1.35 (1.34 is in feature freeze).
I personally very rarely use constant/reference class members, but understand your concerns. Perhaps a BOOST_PARAMETER_RESTRICTED_CTOR (or similarly ugly-named) macro could be included in the library?
I don't think there's a real need to uglify. Usually ctors are pretty simple anyway; I think this macro should just generate the ctor overloads directly instead of doing any forwarding. Daniel, what do you think about that? Note, however, that we have a new, much more powerful, macro system for Boost.Parameter. See http://www.boost-consulting.com/boost/libs/parameter/test/preprocessor.cpp Whatever you do should be compatible with that.
Otherwise, maybe mentioning something about constructors in the faq would be a good idea?
Sure, good idea. Patches would be very welcome.
Also, should the BOOST_PARAMETER_MEMFUN macro be documented?
We're going to document the new macro system.
Or, even better, is there a way of restricting the arguments to only be passed by name using the parameters specification?
Nope. Why do you want to do that?
I'd like to make sure that users have absolutely (well, almost) no possibility of using arguments incorrectly. Consider the following (does not compile):
--- #include
int foo(int index, int low_limit, int high_limit, int buffer_size) { ... }
BOOST_PARAMETER_KEYWORD(tag, index_p) BOOST_PARAMETER_KEYWORD(tag, low_limit_p) BOOST_PARAMETER_KEYWORD(tag, high_limit_p) BOOST_PARAMETER_KEYWORD(tag, buffer_size_p)
struct wrap_foo_args : boost::parameter::parameters< boost::parameter::optionaltag::index_p, boost::parameter::optionaltag::low_limit_p, boost::parameter::optionaltag::high_limit_p, boost::parameter::optionaltag::buffer_size_p
{};
BOOST_PARAMETER_FUN(int, wrap_foo, 0, 4, wrap_foo_args) { return foo(p[index_p|-1], p[low_limit_p|0], p[high_limit_p|255], p[buffer_size_p|1]); }
int foo_with_fixed_high_and_buffer_size(int ndx, int low) { return wrap_foo(low, ndx, high_limit_p = 1, buffer_size_p = 10); // ouch ... }
I think it's awfully nanny-ish to want to do that, but adding such a feature *should* be fairly easy. -- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams wrote:
"Johan Nilsson"
writes: I personally very rarely use constant/reference class members, but understand your concerns. Perhaps a BOOST_PARAMETER_RESTRICTED_CTOR (or similarly ugly-named) macro could be included in the library?
I don't think there's a real need to uglify. Usually ctors are pretty simple anyway; I think this macro should just generate the ctor overloads directly instead of doing any forwarding. Daniel, what do you think about that?
I'm not sure I understand what you are suggesting. Right now we have the new macro system that has constructors that forward to a base class. What are you suggesting that differs from that? -- Daniel Wallin
Daniel Wallin
David Abrahams wrote:
"Johan Nilsson"
writes: I personally very rarely use constant/reference class members, but understand your concerns. Perhaps a BOOST_PARAMETER_RESTRICTED_CTOR (or similarly ugly-named) macro could be included in the library?
I don't think there's a real need to uglify. Usually ctors are pretty simple anyway; I think this macro should just generate the ctor overloads directly instead of doing any forwarding. Daniel, what do you think about that?
I'm not sure I understand what you are suggesting. Right now we have the new macro system that has constructors that forward to a base class. What are you suggesting that differs from that?
Using the macros to generate a family of ctors that replicate the same base/member initializer list and function body, so no base class is needed. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
Daniel Wallin
-
David Abrahams
-
Johan Nilsson