【问题标题】:check if variable is of a class that has specific base class检查变量是否属于具有特定基类的类
【发布时间】:2015-03-26 19:50:17
【问题描述】:

is_base_of来检查A类是否是B的基类。但是如果我没有变量的类型怎么办?

假设我有五个类 A、B、C、D 和 E,并且 D 和 E 分别从 A 和 B 派生。 C 仅从 A 派生。现在我有一个指向 A 的指针,我想知道是否可以将指针强制转换为 B。在这种情况下,我想知道我的 A 指针是指向 D 还是 E 对象,以便我可以将指针强制转换为 B 对象。

我尝试了以下方法,但没有成功。

void foo(const std::shared_ptr<A> & ptr) {
    if (std::is_base_of<B, decltype(*ptr)>::value) {
        doSomething(std::static_pointer_cast<B>(ptr));
    }
}

编辑:foo 不是模板函数,A 和 B 只是我现有类的占位符。

【问题讨论】:

  • 缩小范围,使用dynamic_cast。它会为您检查(将抛出 std::bad_cast
  • @RedAlert 没错!前提是至少有一个虚函数。
  • 好吧,std::dynamic_pointer_cast,它将返回一个空指针,而不是std::bad_cast,以防万一它不起作用。但是,是的,这需要运行时检查。
  • dynamic_cast 也适用于指针,并在失败时返回 null。只有在转换引用时才会抛出 std::bad_cast,因为引用不能为空。
  • @Wintermute:谢谢,std::dynamic_pointer_cast 有效!

标签: c++ c++14 typetraits


【解决方案1】:

如果foo 是模板函数,则必须在模板参数列表中在A 之前定义B。在调用foo 时,您还必须专门输入 B。

如果您的代码按原样提供,那么您必须将 foo 设为模板,并以 A 作为模板的参数。

例子:

#include <memory>

template <typename B>
void doSomething(std::shared_ptr<B> &ptr)
{

}

template <typename B, typename A>
void foo(const std::shared_ptr<A> & ptr) {
    if (std::is_base_of<B, decltype(*ptr)>::value) {
        doSomething(std::static_pointer_cast<B>(ptr));
    }
}

class A { };

class B : public A { };

int _tmain(int argc, _TCHAR* argv[])
{
    std::shared_ptr<A> a(new B);

    foo<B>(a);

    return 0;
}

【讨论】:

  • foo 不是模板函数。
猜你喜欢
  • 2015-04-27
  • 1970-01-01
  • 2010-12-25
  • 2011-03-21
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
相关资源
最近更新 更多