模板函数中的多态

Dem*_*unt 1 c++ polymorphism templates

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

class NotDerived
{

};

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

class Derived : public Base
{

};
Run Code Online (Sandbox Code Playgroud)

由于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

主要功能是这样的:

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

    foo(d);
    foo(b);
    foo(nd);
}
Run Code Online (Sandbox Code Playgroud)

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

有人可以解释为什么CASE_1,CASE_2无法工作而CASE_3可以工作的原因。通过工作,我的意思是在没有dynamic_casting的情况下尽可能地调用base_method。

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

Nat*_*ica 5

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

使用的问题

if (std::is_base_of_v<Base, T>)
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

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

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
}
Run Code Online (Sandbox Code Playgroud)

而现在,如果std::is_base_of_v<Base, T>为false,some_instance.base_method();则将被丢弃且从不编译。