Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板函数中的多态性_C++_Templates_Polymorphism - Fatal编程技术网

C++ 模板函数中的多态性

C++ 模板函数中的多态性,c++,templates,polymorphism,C++,Templates,Polymorphism,我想使用模板函数来处理多态类和非多态类。这里有3个基本类 class NotDerived { }; class Base { public: virtual ~Base() {} void base_method() {} }; class Derived : public Base { }; 因为NotDevertive没有虚拟函数,所以我不能使用dynamic_cast,接下来是模板函数: template<class T> auto foo(T&am

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

class NotDerived
{

};

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

class Derived : public Base
{

};
因为NotDevertive没有虚拟函数,所以我不能使用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);
    }
}
现在我明白了为什么CASE_1在传递
nd
变量的情况下不起作用,但我不明白的是,为了调用base_方法,我必须显式地在lamb2函数中强制转换
某个_实例

有人能解释为什么案例1、案例2不起作用,而案例3起作用吗。 通过工作,我的意思是在可能的情况下调用base_方法,而不使用动态_转换


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

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

使用的问题

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

现在如果
std::is_base_of_v
为false,则
某个实例.base_方法()将被丢弃并且永远不会编译。

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

使用的问题

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

现在如果
std::is_base_of_v
为false,则
某个实例.base_方法()将被丢弃,并且永远不会编译。

您应该查看有关的官方文档。if中的代码在任何情况下都会被编译,所以它不会编译

如果您使用的是C++17,则可以将其替换为constexpr If,它将在编译期间计算If中的信息,并在需要时忽略代码:

template<class T>
auto foo(T& some_instance) {
    if constepxr (std::is_base_of_v<Base, T>) {
        auto lamb2 = [](T& some_instance) {((Base&)some_instance).base_method(); }
        lamb2(some_instance);
    } else {
        // Whatever you want to do
    }
}

你应该看一下有关这件事的官方文件。if中的代码在任何情况下都会被编译,所以它不会编译

如果您使用的是C++17,则可以将其替换为constexpr If,它将在编译期间计算If中的信息,并在需要时忽略代码:

template<class T>
auto foo(T& some_instance) {
    if constepxr (std::is_base_of_v<Base, T>) {
        auto lamb2 = [](T& some_instance) {((Base&)some_instance).base_method(); }
        lamb2(some_instance);
    } else {
        // Whatever you want to do
    }
}

您的第二个示例不是专门化,而是重载。如果传递了派生类,它也不起作用,因为模板将产生精确匹配。第二个示例不是专门化,而是重载。如果传递了派生类,它也不起作用,因为模板将生成精确匹配。Case_3可以工作,因为它可以编译,但不调用base_方法。我的目标不是从nd调用base_方法,我只是希望模板函数决定是否调用base_method@Demaunt
autolamb2=[](T&some_实例){((Base&)some_实例).Base_方法();};lamb2(某个实例)
确实调用了
base\u方法
,这是UB,因为
nd
不是从
base
派生出来的。Case\u 3可以工作,因为它可以编译,但不调用base\u方法。我的目标不是从nd调用base_方法,我只是希望模板函数决定是否调用base_method@Demaunt
autolamb2=[](T&some_实例){((Base&)some_实例).Base_方法();};lamb2(某个实例)
确实调用了
base\u方法
,这是UB,因为
nd
不是从
base
派生的。我不想从nd调用base\u方法。我想把变量传递到模板函数中,让模板函数决定是调用base_方法还是passo对不起,我误读了你的代码,我的错;)我不想从nd调用base_方法。我想把变量传递到模板函数中,让模板函数决定是调用base_方法还是passo对不起,我误读了你的代码,我的错;)
template<class T>
auto foo(T& some_instance) {
   // Do whatever
}

auto foo(Base& some_instance) {
    auto lamb2 = [](T& some_instance) {((Base&)some_instance).base_method(); }
    lamb2(some_instance);
}
template <typename T>
typename std::enable_if<std::is_base_of<Base, T>::value, void>::type
foo() {
   auto lamb2 = [](T& some_instance) {((Base&)some_instance).base_method(); }
   lamb2(some_instance); 
}

template <typename T>
typename std::enable_if<!std::is_base_of<Base, T>::value, void>::type
foo() {
   // Do whatever
}