Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using the Boost Parameter Library in a class hierarchy

0 views
Skip to first unread message

Alf P. Steinbach

unread,
Mar 10, 2010, 2:09:21 AM3/10/10
to
Some time ago (years?) I posted a question here about ideas for implementing
option packs, corresponding to optional arguments, that could be extended
through derivation, and came up with a pure C++ solution -- another
possibility mentioned then was code generation using a script.

Looking into essentially the same issue I now found that it's /possible/ to use
the Boost Parameter Library, as exemplified by ...


<code>
#include <iostream>
using namespace std;

#include <boost/parameter.hpp>

namespace abstractButton {
BOOST_PARAMETER_NAME( none ) // Just to create "empty" ArgumentPack.
BOOST_PARAMETER_NAME( hTextAlign )
} // namespace abstractButton

struct AbstractButton
{
struct Params
{
int hTextAlign;

template< class ArgumentPack >
Params( ArgumentPack const& args )
: hTextAlign( args[abstractButton::_hTextAlign | 0] )
{}
};

void show( Params const& params )
{
cout << params.hTextAlign << endl;
}

AbstractButton()
{ show( abstractButton::_none = 0 ); }

template< class ArgumentPack >
AbstractButton( ArgumentPack const& args )
{ show( args ); }
};

namespace checkBox {
using namespace abstractButton;
namespace tag { using namespace abstractButton::tag; }
BOOST_PARAMETER_NAME( isAuto )
} // namespace checkBox

struct CheckBox: AbstractButton
{
struct Params: AbstractButton::Params
{
bool isAuto;

template< class ArgumentPack >
Params( ArgumentPack const& args )
: AbstractButton::Params( args )
, isAuto( args[checkBox::_isAuto | true] )
{}
};

void show( Params const& params )
{
cout << boolalpha << params.isAuto << endl;
}

CheckBox()
: AbstractButton( checkBox::_none = 0 )
{ show( checkBox::_none = 0 ); }

template< class ArgumentPack >
CheckBox( ArgumentPack const& args )
: AbstractButton( args )
{ show( args ); }
};

int main()
{
using namespace checkBox;

CheckBox widget1;
cout << endl;

CheckBox widget2((
_hTextAlign = 1
));
cout << endl;

CheckBox widget3((
_hTextAlign = 1,
_isAuto = false
));
}
</code>


I'm guessing that there must be a simpler way to create an empty ArgumentPack,
but that's not my main question.

I see two problems with the above:

A) A kind of unstrict typing: the constructors will accept any boost
ArgumentPack whatsoever, with any irrelevant options. Can this be
avoided without introducing undue complexity & verbosity?

B) That default values must be specified where the arguments are extracted.
In this code I centralized that by defining Params classes to unpack the
supplied arguments. But I'm not sure how well that idea plays in more
real code?

A sort of academic additional problem: I'm guessing that the use of the comma
operator in the calls involves O(n^2) copying, but I can't see that it would be
a practical problem?

And since I've never used this Boost library before, is the way I'm using it
reasonable, or is there a Better Way (or Ways)?


Cheers,

- Alf

Alf P. Steinbach

unread,
Mar 10, 2010, 5:07:41 AM3/10/10
to
* Alf P. Steinbach:
> ...

Oops. I was stupid. Now I'm much smarter, just in the span of some hours. :-)


<code>
#include <iostream>
using namespace std;

#include <boost/parameter.hpp>

namespace abstractButton {
BOOST_PARAMETER_NAME( none ) // Just to create "empty" ArgumentPack.
BOOST_PARAMETER_NAME( hTextAlign )
} // namespace abstractButton

struct AbstractButton
{
struct Params
{
int hTextAlign;

template< class ArgumentPack >
Params( ArgumentPack const& args )
: hTextAlign( args[abstractButton::_hTextAlign | 0] )
{}
};

void show( Params const& params )
{
cout << params.hTextAlign << endl;
}

AbstractButton(
Params const& params = Params( abstractButton::_none = 0 )
)
{ show( params ); }
};

namespace checkBox {
using namespace abstractButton;
namespace tag { using namespace abstractButton::tag; }
BOOST_PARAMETER_NAME( isAuto )
} // namespace checkBox

struct CheckBox: AbstractButton
{
struct Params: AbstractButton::Params
{
bool isAuto;

template< class ArgumentPack >
Params( ArgumentPack const& args )
: AbstractButton::Params( args )
, isAuto( args[checkBox::_isAuto | true] )
{}
};

void show( Params const& params )
{
cout << boolalpha << params.isAuto << endl;
}

CheckBox(
Params const& params = Params( checkBox::_none = 0 )
)
: AbstractButton( params )
{ show( params ); }
};

int main()
{
using namespace checkBox;

CheckBox widget1;
cout << endl;

CheckBox widget2((
_hTextAlign = 1 // OK
));
cout << endl;

CheckBox widget3((
_hTextAlign = 1, // OK
_isAuto = false // OK
));
}
</code>


Questions as in original article.

Cheers,

- Alf

0 new messages