Germán Diago
Germán Diago

Reputation: 7663

forward-declaring boost.type_erasure reference type

I am using boost.type_erasure in my codebase. So far the experience, given what it enables, has been very good.

I want to be able to forward-declare a " type-erased reference type" for my API. This leaves outside using and typedef because they do not allow forward declarations.

For a value type everything is fine:

class any_game_state : public
boost::type_erasure::any<
boost::mpl::vector<has_enter<void ()>,
                   has_update<bool (std::chrono::milliseconds)>,
                   has_exit<int ()>,
                   has_get_resolution<std::pair<int, int> (),
                                      const
                                      boost::type_erasure::_self>,
                   has_get_position<std::pair<int, int> (),
                                    const
                                    boost::type_erasure::_self>,
                   has_get_scene_root<boost::any (), const
                                      boost::type_erasure::_self>,
                   boost::type_erasure::copy_constructible<>,
                   boost::type_erasure::relaxed>> {
    using base = boost::type_erasure::any<...identical_contents>;

    using base::base;
};

But when I try to do the same for its corresponding reference, it is not working:

class any_game_state_ref : public
boost::type_erasure::any<
boost::mpl::vector<has_enter<void ()>,
                   has_update<bool (std::chrono::milliseconds)>,
                   has_exit<int ()>,
                   has_get_resolution<std::pair<int, int> (),
                                      const
                                      boost::type_erasure::_self>,
                   has_get_position<std::pair<int, int> (),
                                    const
                                    boost::type_erasure::_self>,
                   has_get_scene_root<boost::any (), const
                                      boost::type_erasure::_self>,
                   boost::type_erasure::copy_constructible<>,
                   boost::type_erasure::relaxed>,
                   boost::type_erasure::_self&> {
    using base = boost::type_erasure::any<...identical_contents>;

    using base::base;
};

If I use using for the "reference type" everything works fine, but I lose the ability to forward-declare the reference type.

The error I get is the following:

In file included from src/barvie/controller/game_action_state.cpp:3: In file included from /usr/local/include/boost/type_erasure/any_cast.hpp:24: /usr/local/include/boost/type_erasure/any.hpp:1290:12: error: no type named 'type' in 'boost::disable_if, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::is_const, mpl_::bool_, mpl_::bool_, mpl_::bool_ >, void>'

::type* = 0 ~~~^~~~ ../libbarvie/src/barvie/controller/any_game_state.hpp:95:17: note: in instantiation of member function 'boost::type_erasure::any, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::type_erasure::_self &>::any' requested here using base::base; ^ src/barvie/controller/game_action_state.cpp:291:18: note: while substituting deduced template arguments into function template 'any_game_state_ref' [with Concept2 = boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, Tag2 = boost::type_erasure::_self] (this, ^ In file included from src/barvie/controller/game_action_state.cpp:3: In file included from /usr/local/include/boost/type_erasure/any_cast.hpp:24: /usr/local/include/boost/type_erasure/any.hpp:1323:12: error: no type named 'type' in 'boost::disable_if, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::is_const, mpl_::bool_, mpl_::bool_, mpl_::bool_ >, void>' ::type = 0 ~~~^~~~ ../libbarvie/src/barvie/controller/any_game_state.hpp:95:17: note: in instantiation of member function 'boost::type_erasure::any, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::type_erasure::_self &>::any' requested here using base::base; ^ src/barvie/controller/game_action_state.cpp:291:18: note: while substituting deduced template arguments into function template 'any_game_state_ref' [with Concept2 = boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, Tag2 = boost::type_erasure::_self &] (*this,

Upvotes: 1

Views: 135

Answers (1)

Germ&#225;n Diago
Germ&#225;n Diago

Reputation: 7663

I found a solution. The solution is to give up on inherited constructors for the reference type, instead of the inherited constructor I used an equivalent by-hand inherited constructor. It seems that maybe something about templates mixed with inherited constructors did not play well:

template <class...Args>
any_game_state_ref(Args &&... args) : base(std::forward<Args>(args)...)
{}

This did the trick and now I can forward declare type erased references also.

Upvotes: 1

Related Questions