C ++中的静态多态性 [英] Static polymorphism in C++

查看:140
本文介绍了C ++中的静态多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <iostream>

template<typename Impl>
struct renderer{
    void get(){
        static_cast<Impl*>(this)->get();
    }
};
struct open_gl : public renderer<open_gl>{
    void get(){
        std::cout << "OpenGL" << std::endl;
    }
};
struct direct_draw : public renderer<direct_draw>{
    void get(){
        std::cout << "DX" << std::endl;
    }
};
template<typename T>
void print_renderer(renderer<T> r){
    r.get();
}
int main() {
    auto gl = open_gl();
    auto dx = direct_draw();
    print_renderer(gl);
    print_renderer(dx);
}




  1. print_renderer的参数为 void
    print_renderer(const renderer< T>& r)

    无法将'this'指针从'const renderer< open_gl>'转换为'renderer< open_gl> &'
    `

为什么在重命名方法时会出现运行时错误 get 在open_gl中从
get到get1?应该不会触发编译器错误? 错误=堆栈溢出

Why do I get a runtime error when I rename the method get in open_gl from get to get1? Shouldn't this trigger a compiler error? Error = Stack overflow

最新的MSVC

推荐答案

1)因为 get 不是 const 成员函数:它不能允许不修改你的(const)参数。

1) Because get is not a const member function : it cannot make the promise of not modify your (const) argument.

您可以将 get 声明为 const ,并编译正确:

You could declare get as const, and it compiles fine :

void get() const { ... }

2)基本 get 方法将被调用,进入无限递归:Stack Overflow。

2) The base get method will be called, going into infinite recursion : Stack Overflow.

如果您声明了函数 override (它需要是虚拟的),编译器会抛出一个错误,如果它确实不覆盖基础方法:

If you declare your function override (it needs to be virtual), the compiler will throw an error if it does not indeed override a base method :

void get1() override  { ... } // Compiler error
void get() override   { ... } // Ok






注意

标题是C ++中的静态多态性,但我认为你误解了什么是静态多态性:它不(必须)使用继承(如你所做的)。相反,模板编译时鸭型将为你静态地解析函数调用。

The title is "Static polymorphism in C++", but I think that you misunderstood what is static polymorphism : it does not (have to) make use of inheritance (as you did). Rather, the templates compile-time duck typing will statically "resolve" function calls for you.

也就是说,你不需要相关的类型,你不需要基本 renderer 类,你可以简单地做以下(在这种情况下,重命名为 get1 将会导致编译器错误):

That is, you don't need related types, you don't need the base renderer class at all, and you can simply do the following (in which case, renaming to get1 will cause a compiler error) :

#include <iostream>

struct open_gl {
    void get(){
        std::cout << "OpenGL" << std::endl;
    }
};
struct direct_draw {
    void get(){
        std::cout << "DX" << std::endl;
    }
};

template<typename T>
void print_renderer(T r){
    r.get();
}

int main() {
    auto gl = open_gl();
    auto dx = direct_draw();
    print_renderer(gl);
    print_renderer(dx);
}

Live demo

Live demo

这篇关于C ++中的静态多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆