Как разыграть, если является производным классом от определенного базового класса - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь привести объект к классу, если он получен из другого определенного класса или приведен к базовым типам (int, float string и т. Д.) В методе шаблона, но я получаю те же ошибки.

Код:

#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 голосов
/ 06 ноября 2018

Вы хотите использовать C ++ 17, если constexpr:

    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();
}

И аналогично для другой ветки.

После комментария вы действительно знаете, что T - это A, поэтому используйте static_cast.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...