[type_erasure] issue when taking any<> by const ref

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.
for(const some_any_t& : v) { }
However if I iterate by taking element by const ref 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.

AMDG On 11/12/2012 03:33 PM, Thomas Petit wrote:
I'm playing with the boost type erasure library (from the sandbox) and hit some issues.
<snip> 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.
Fixed.
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)
You need to use has_member<void(), const _self> for const member functions.
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 ?
In Christ, Steven Watanabe

Fixed. Nice !
You need to use has_member<void(), const _self> for const member functions.
Ok, I understand now. I didn't realize that has_member<void()> was actually a shortcut to has_member<void(), _self>. Thanks. 2012/11/13 Steven Watanabe <watanabesj@gmail.com>
AMDG
On 11/12/2012 03:33 PM, Thomas Petit wrote:
I'm playing with the boost type erasure library (from the sandbox) and hit some issues.
<snip> 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.
Fixed.
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)
You need to use has_member<void(), const _self> for const member functions.
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 ?
In Christ, Steven Watanabe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Steven Watanabe
-
Thomas Petit