|
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
Hi,
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
defined by BOOST_TYPE_ERASURE_FREE
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<>>>
any_free_t;
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>>
any_member_t;
int main()
{
any_free_t af1(5);
any_free_t af2(5.0);
std::vector<any_free_t> v;
v.push_back(af1);
v.push_back(af2);
for(any_free_t& af : v)
{
free(af);
}
Base b;
Derived d;
std::vector<any_member_t> v2;
v2.push_back(b);
v2.push_back(d);
for(any_member_t& am : v2)
{
am .member();
}
}
.......................................................
In the previous code, if add a const here :
for(const any_free_t& af : v)
{
free(af);
}
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 ?
Thanks.
Thomas.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk