C++中的静态多态性

Mai*_*ein 11 c++ polymorphism

#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);
}
Run Code Online (Sandbox Code Playgroud)
  1. 为什么我不能将print_renderer的参数更改为void print_renderer(const renderer<T> &r)cannot convert 'this' pointer from 'const renderer<open_gl>' to 'renderer<open_gl> &' `

  2. 当我将getopen_gl中的方法从get 重命名为get1 时,为什么会出现运行时错误?这不应该触发编译错误吗?Error = Stack overflow

**注意我使用的是最新的MSVC

qua*_*dev 12

1)因为get不是const成员函数:它不能承诺不修改你的(const)参数.

你可以声明getconst,并编译好:

void get() const { ... }
Run Code Online (Sandbox Code Playgroud)

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

如果你声明你的函数override(它需要是虚函数),如果编译器确实没有覆盖基本方法,它将抛出一个错误:

void get1() override  { ... } // Compiler error
void get() override   { ... } // Ok
Run Code Online (Sandbox Code Playgroud)

注意:

标题是"C++中的静态多态",但我认为你误解了什么是静态多态:它不(必须)使用继承(就像你做的那样).相反,模板编译时鸭子类型将为您静态"解析"函数调用.

也就是说,您不需要相关类型,根本不需要基renderer类,您只需执行以下操作(在这种情况下,重命名get1 导致编译器错误):

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

现场演示


Bar*_*icz 5

  1. 因为get没有标记const.
  2. 因为使用了基类方法(与演员无关),并且它进入无限循环.