Boost logo

Boost :

Subject: [boost] [type_erasure] issue when taking any<> by const ref
From: Thomas Petit (thomas.petit33_at_[hidden])
Date: 2012-11-12 18:33:06

I'm playing with the boost type erasure library (from the sandbox) and hit
some issues.

Imagine that I have an any accepting some concept :
> typedef any<concept1<>, concept2<>> some_any_t;
and a std::vector to put a few any in it :
> std::vector<some_any_t> v;
Then If I iterate over the vector by taking each element by reference
>for(some_any_t& : v)
everything is fine and consistent with why I expect.

However if I iterate by taking element by const ref
>for(const some_any_t& : v)
then some issue appears.

Here is an example showing the problems (with one any using a concept
 and one any using a concept defined by BOOST_TYPE_ERASURE_MEMBER)


#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/free.hpp>
#include <boost/type_erasure/member.hpp>

namespace mpl = boost::mpl;
namespace te = boost::type_erasure;

template <typename T>
void free(const T& t)
    std::cout << typeid(t).name() << std::endl;
    std::cout << "default free\n";

void free(const int& i)
    std::cout << typeid(i).name() << std::endl;
    std::cout << "int\n";

BOOST_TYPE_ERASURE_FREE((has_free), free, 1);
template<class T = te::_self>
struct free_concept : mpl::vector<has_free<void(const T&)> > {};

typedef te::any<mpl::vector<te::copy_constructible<>, free_concept<>>>

struct Base
    virtual void member() const
        std::cout << "Base member\n";

struct Derived : public Base
    virtual void member() const
        std::cout << "Derived member\n";

BOOST_TYPE_ERASURE_MEMBER((has_member), member, 0)
struct member_concept : mpl::vector<has_member<void()> > {};
typedef te::any<mpl::vector<te::copy_constructible<>, member_concept>>

int main()
    any_free_t af1(5);
    any_free_t af2(5.0);
    std::vector<any_free_t> v;

    for(any_free_t& af : v)

    Base b;
    Derived d;
    std::vector<any_member_t> v2;

    for(any_member_t& am : v2)
        am .member();

In the previous code, if add a const here :

for(const any_free_t& af : v)

then instead of calling the int overload of the free function and the
template overload with a double type,
the templated free function is called both time but, unfortunately the type
of T is always the same as the any.

Another point, if I add a const here :
for(const any_member_t& am : v2)
     am .member();
then I get a compile error. (with visual 2012 and gcc 4.7)

I'm a bit puzzled by this behavior. Are any<> types never supposed to be
taken by const ref ?
How can we iterate over anys while preserving constness ?


Boost list run by bdawes at, gregod at, cpdaniel at, john at