Boost logo

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