c++ - 模板函数中的多态性

标签 c++ templates polymorphism

我想使用模板函数来处理多态类和非多态类。这里有 3 个基本类。

class NotDerived
{

};

class Base
{
public:
    virtual ~Base() {}
    void base_method() {}
};

class Derived : public Base
{

};

由于 NotDerived 没有虚函数,我不能使用 dynamic_cast,接下来是模板函数:

template<class T>
auto foo(T& some_instance)
{
    if (std::is_base_of_v<Base, T>)
    {
        //CASE_1: Works for d and b
        /*some_instance.base_method();*/

        //CASE_2: Works for d and b
        /*auto lamb1 = [](T& some_instance) {some_instance.base_method(); };
        lamb1(some_instance);*/


        auto lamb2 = [](T& some_instance) {((Base&)some_instance).base_method(); };
        lamb2(some_instance);
    }
}

主要功能是这样做的:

void main()
{
    Derived d{};
    Base b{};
    NotDerived nd{};

    foo(d);
    foo(b);
    foo(nd);
}

现在我明白了为什么 CASE_1 在传递 nd 变量的情况下不起作用,但我无法理解的是我必须在 lamb2 函数中显式转换 some_instance以便调用 base_method。

谁能解释为什么 CASE_1、CASE_2 不起作用,而 CASE_3 起作用。 我所说的工作是指在没有 dynamic_casting 的情况下尽可能调用 base_method。

也可以使用 constexpr 来处理静态多态或编译多态的这种情况(希望这样命名是合法的)

最佳答案

情况 3 不起作用。您正在转换为不相关的类型并使用该临时函数来调用未定义行为的函数。

使用的问题

if (std::is_base_of_v<Base, T>)
{
    //...
}

...中的所有内容吗?部分需要能够编译。您需要的是一种仅在 T 时调用该代码的方法。是你想要的类型。您可以使用 constexpr if喜欢

if constexpr (std::is_base_of_v<Base, T>)
{
    some_instance.base_method();
}
else
{
    // do something else since T isn't a Base or derived from Base
}

现在如果std::is_base_of_v<Base, T>那么 some_instance.base_method(); 是假的将被丢弃并且永远不会编译。

关于c++ - 模板函数中的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55341631/

相关文章:

c++ - 使用变体时,模板化的 child 不被接受为 parent

c# - 你能在运行时使用 C# 实例化模板类吗

haskell - 多态种类的用途是什么?

c++ - 为什么此函数多次输出一个单词而不是一个单词?

c++ - 是否可以将自定义小部件添加到 QListView 中?

c++ - 使用 std::enable_if 声明带有可变模板参数的括号运算符

c++ - 为什么这个方法不被覆盖?

c++ - 派生类映射

c++ - 监控一个线程的状态

c++ - 如何在 C++ 中安全地比较 32 位整数与 64 位整数以及如何在内部比较有符号整数?