|
Boost : |
From: Sven Van Echelpoel (sven.vanechelpoel_at_[hidden])
Date: 2007-11-11 10:42:10
Hi,
I discovered that the named arguments to class templates cannot be
abstract type with Boost 1.34
Here's an example of what I mean:
#include <boost/parameter.hpp>
struct foo {
virtual void not_defined() = 0;
};
struct derived_foo : foo {};
BOOST_PARAMETER_TEMPLATE_KEYWORD(param_name)
typedef boost::parameter::parameters<
boost::parameter::optional<
tag::param_name
>
> signature;
template<
typename T
>
struct X
{
typedef T type;
};
template<
typename Arg = boost::parameter::void_
>
struct bar
{
// Create ArgumentPack
typedef typename
signature::bind<
Arg
>::type
args;
typedef typename boost::parameter::binding<
args
, tag::param_name, foo
>::type type;
};
struct foobar :
bar< param_name<derived_foo> > // This produces an error
//bar< param_name<foo > // Doesn't work either
//bar<> // relying on the default seems to work
{
};
When I try to compile the above code, I get the following errors on VC 7.1:
fails_abstract_class.cpp
d:\Folders\Projects\boost_1_34_0\boost\parameter\aux_\arg_list.hpp(266)
: error C2259: 'derived_foo' : cannot instantiate abstract class
due to following members:
'void foo::not_defined(void)' : pure virtual function was not
defined
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(4)
: see declaration of 'foo::not_defined'
d:\Folders\Projects\boost_1_34_0\boost\parameter\binding.hpp(58)
: see reference to class template instantiation
'boost::parameter::aux::arg_list<TaggedArg,Next>' being compiled
with
[
TaggedArg=boost::parameter::aux::make_arg_list0<boost::parameter::aux::make_items<boost::parameter::optional<tag::param_name>,param_name<derived_foo>,boost::parameter::aux::make_items<boost::parameter::void_,boost::parameter::void_,boost::parameter::aux::make_items<boost::parameter::void_,boost::parameter::void_,boost::parameter::aux::make_items<boost::parameter::void_,boost::parameter::void_,boost::parameter::aux::make_items<boost::parameter::void_,boost::parameter::void_,boost::mpl::identity<boost::parameter::void_>>>>>>::type,boost::parameter::parameters<boost::parameter::optional<tag::param_name>>::deduced_list,boost::parameter::aux::tag_template_keyword_arg,boost::mpl::true_,boost::parameter::aux::set0,boost::parameter::aux::empty_arg_list,boost::parameter::void_>::tagged,
Next=boost::parameter::aux::empty_arg_list
]
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(40)
: see reference to class template instantiation
'boost::parameter::binding<Parameters,Keyword,Default>' being compiled
with
[
Parameters=bar<param_name<derived_foo>>::args,
Keyword=tag::param_name,
Default=foo
]
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(46)
: see reference to class template instantiation 'bar<Arg>' being compiled
with
[
Arg=param_name<derived_foo>
]
d:\Folders\Projects\boost_1_34_0\boost\parameter\aux_\arg_list.hpp(272)
: error C2259: 'derived_foo' : cannot instantiate abstract class
due to following members:
'void foo::not_defined(void)' : pure virtual function was not
defined
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(4)
: see declaration of 'foo::not_defined'
d:\Folders\Projects\boost_1_34_0\boost\parameter\aux_\arg_list.hpp(355)
: error C2259: 'derived_foo' : cannot instantiate abstract class
due to following members:
'void foo::not_defined(void)' : pure virtual function was not
defined
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(4)
: see declaration of 'foo::not_defined'
d:\Folders\Projects\boost_1_34_0\boost\parameter\aux_\arg_list.hpp(361)
: error C2259: 'derived_foo' : cannot instantiate abstract class
due to following members:
'void foo::not_defined(void)' : pure virtual function was not
defined
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(4)
: see declaration of 'foo::not_defined'
d:\Folders\Projects\boost_1_34_0\boost\parameter\aux_\arg_list.hpp(367)
: error C2259: 'derived_foo' : cannot instantiate abstract class
due to following members:
'void foo::not_defined(void)' : pure virtual function was not
defined
d:\Folders\Projects\components\dev\projects\test_boost_param_abstract_classes\test_boost_param_abstract_classes\fails_abstract_class.cpp(4)
: see declaration of 'foo::not_defined'
However, if I rely on the default established when binding the argument,
everything just works. Is there something I'm doing wrong?
For now I have a workaround. I wrap the argument types in mpl::identity
and extract them again afterwards. This works, but it is not pretty.
#include <boost/parameter.hpp>
#include <boost/mpl/identity.hpp>
struct foo {
virtual void not_defined() = 0;
};
struct derived_foo : foo {};
BOOST_PARAMETER_TEMPLATE_KEYWORD(param_name)
typedef boost::parameter::parameters<
boost::parameter::optional<
tag::param_name
>
> signature;
template<
typename T
>
struct X
{
typedef T type;
};
template<
typename Arg = boost::parameter::void_
>
struct bar
{
// Create ArgumentPack
typedef typename
signature::bind<
boost::mpl::identity<Arg>
>::type
args;
typedef typename boost::parameter::binding<
args
, tag::param_name, boost::mpl::identity<foo>
>::type type_provider;
typedef typename type_provider::type type;
};
struct foobar :
bar< param_name<derived_foo> >
//bar<>
{
};
Any thoughts on this one?
Thanks,
Sven
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk