Search code examples
c++boostboost-type-erasure

converting boost type erased type back to original type gives me boost::bad_any_cast


I'm new to boost type erasure and I'm having problems converting the objects back into their original type. From how I understand the boost documentation I should be able to use boost::any_cast to convert the type-erased object back to their original type, but the following code fails with a bad_any_cast exception. What am I doing wrong? Thanks a bunch!

https://www.boost.org/doc/libs/1_67_0/doc/html/boost/any_cast.html

BOOST_TYPE_ERASURE_MEMBER((has_x), x, 0)

namespace bte = boost::type_erasure;
using xConcept = boost::mpl::vector<has_x <float(), bte::_self> ,
                                                    bte::copy_constructible<>,
                                                    bte::relaxed>;

using AnyXobject = bte::any<xConcept, bte::_self>;

struct xThing{
  float x(){
    return 4.;
  }
  float y(){
    return 5.;
  }
};

int main(){
  // instance of concrete implementation
  xThing i; 
  // using concrete implementation to construct type erased object
  AnyXobject xconc(i); 
  // calling x() correctly prints 4
  std::cout << xconc.x() << std::endl; 

  // converting back to concrete implementation fails with boost::bad_any_cast at runtime
  auto j = boost::any_cast<xThing>(xconc);
  return 0;
}

Solution

  • You need to call boost::type_erasure::any_cast

    Here is the corrected program:

    #include <boost/type_erasure/any.hpp>
    #include <boost/type_erasure/any_cast.hpp>
    #include <boost/type_erasure/member.hpp>
    #include <iostream>
    
    BOOST_TYPE_ERASURE_MEMBER((has_x), x, 0)
    
    namespace bte = boost::type_erasure;
    using xConcept = boost::mpl::vector<has_x <float(), bte::_self> ,
    bte::copy_constructible<>,
    bte::relaxed>;
    
    using AnyXobject = bte::any<xConcept, bte::_self>;
    
    struct xThing{
        float x(){
            return 4.;
        }
        float y(){
            return 5.;
        }
    };
    
    int main(){
        // instance of concrete implementation
        xThing i;
        // using concrete implementation to construct type erased object
        AnyXobject xconc(i);
        // calling x() correctly prints 4
        std::cout << xconc.x() << std::endl;
    
        // converting back to concrete implementation fails with boost::bad_any_cast at runtime
        auto j = bte::any_cast<xThing>(xconc);
        return 0;
    }