从boost :: any确定父类

时间:2009-11-20 07:06:44

标签: c++ boost

我是否知道有没有办法从boost :: any中确定父类?

#include <iostream>
#include <boost/any.hpp>

class a {
public:
    virtual ~a() {}
};

class b : public a {
};

bool is_class_a(const boost::any& any)
{
    return boost::any_cast<a>(&any) != 0;
}

bool is_class_a_v2(const boost::any& any)
{
    try
    {
        boost::any_cast<a>(any);
        return true;
    }
    catch(const boost::bad_any_cast &)
    {
        return false;
    }
}

int main()
{
    std::cout<< is_class_a(b())<< std::endl;    // return 0. but i wish to return 1.
    std::cout<< is_class_a(a())<< std::endl;    // return 1.

    std::cout<< is_class_a_v2(b())<< std::endl; // return 0. but i wish to return 1.
    std::cout<< is_class_a_v2(a())<< std::endl; // return 1.
}

3 个答案:

答案 0 :(得分:2)

boost::any的设计使得它拥有强大的信息对象,其身份并不重要。如果您想使用多态类型,那么您可以使用指向基类的指针或boost::shared_ptr使用基类而不是boost::any

答案 1 :(得分:0)

这就是为什么它不起作用:any_cast是一个模板。 boost :: any使用“type erasure”,这意味着实际类型隐藏在某种类型中性的抽象接口之后。 any_cast实现可用的唯一信息是void*指针和type_info对象。但在这种情况下,没有dynamic_cast运算符支持转换。因此any_cast<T>只是将存储对象的type_info对象与typeid(T)进行比较,如果它们与reinterpret_cast指针匹配void*指针。

如果你想使用多态,你应该使用一些其他包装类而不是boost :: any(可能类似于“clone_ptr”,“shared_ptr”或你自己的专用于你的基类的包装器。)

答案 2 :(得分:-1)

struct a {
  virtual ~a() {}

  template<typename T>
  inline static bool is_subclass( T const & x) { 
    return dynamic_cast<a const *>( &x ) != NULL ; 
  }

};

struct b : public a {
};
struct c { virtual ~c() {} } ;

int main() {
  a x ; b y; c z ;
  std::cout << a::is_subclass(x) << std::endl;
  std::cout << a::is_subclass(y) << std::endl;
  std::cout << a::is_subclass(z) << std::endl;
  return 0 ;
}

请注意,dynamic_cast需要多态类型才能工作。