如何强制转换是否为特定基类的派生类

时间:2018-11-06 18:09:44

标签: c++ templates inheritance casting

我试图将对象强制转换为类,如果它是从另一个特定类派生的,或者在模板方法中强制转换为基本类型(int,浮点字符串等),但是我遇到相同的错误。

代码:

#include <string>
#include <iostream>

//Base class
class A
{
public:
    virtual ~A() = default;
    std::string Get() {
        return "A";
    };
};

//Derived class
class B : public A
{
public:
    virtual ~B() = default;
    std::string Get() {
        return "B";
    };
};

class C
{
public:
    template <typename T>
    void Echo(T* t)
    {
        if (std::is_base_of<A, T>::value)
        {
            //complex types, derived from A
            std::cout << dynamic_cast<A*>(t)->Get();
        }
        else
        {
            //basic types(int, float, string etc...)
            std::cout << *t;
        }
    }
};

int main()
{
    C c;
    c.Echo(new int(12345));
    c.Echo(new B());

    return 0;
}

错误:

error: cannot dynamic_cast ‘t’ (of type ‘int*’) to type ‘class A*’ (source is not a pointer to class)
error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘B’)
.
.
.

有人知道如何做这样的事情,谢谢吗?

1 个答案:

答案 0 :(得分:2)

如果要使用constexpr,则要使用C ++ 17:

    if constexpr(std::is_base_of<A, T>::value)
    {
        //complex types, derived from A
        std::cout << static_cast<A*>(t)->Get();
    }
    else
    {
        //basic types(int, float, string etc...)
        std::cout << *t;
    }

问题在于,即使您在编译时就知道T是int*,经典的if仍会评估所有分支。

另一种选择是使用std::enable_if,例如:

template <typename T>
std::enable_if<std::is_base_of<A, T>::value, void> Echo(T* t)
{
    std::cout << dynamic_cast<A*>(t)->Get();
}

与其他分支类似。

评论后,实际上,您知道TA,所以请使用static_cast