C++ C+中的静态多态性+; #包括 模板 结构渲染器{ void get(){ 静态_cast(this)->get(); } }; 结构open\u gl:公共渲染器{ void get(){ 标准::cout 因为get未标记const 因为使用了基类方法(与cast无关),它进入无限循环
1)因为C++ C+中的静态多态性+; #包括 模板 结构渲染器{ void get(){ 静态_cast(this)->get(); } }; 结构open\u gl:公共渲染器{ void get(){ 标准::cout 因为get未标记const 因为使用了基类方法(与cast无关),它进入无限循环,c++,polymorphism,C++,Polymorphism,1)因为get不是const成员函数:它不能保证不修改(const)参数 您可以将get声明为const,它可以很好地编译: #include <iostream> template<typename Impl> struct renderer{ void get(){ static_cast<Impl*>(this)->get(); } }; struct open_gl : public renderer<op
get
不是const
成员函数:它不能保证不修改(const)参数
您可以将get
声明为const
,它可以很好地编译:
#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);
}
2)将调用baseget
方法,进入无限递归:堆栈溢出
如果您声明了函数(它需要是虚拟的),如果编译器确实没有重写基方法,它将抛出一个错误:
void get() const { ... }
注意: 标题是“C++中的静态多态性”,但我认为您误解了什么是静态多态性:它不(必须)像您那样使用继承。相反,模板编译时duck类型将静态地为您“解析”函数调用 也就是说,您不需要相关类型,根本不需要基本的
呈现程序
类,只需执行以下操作(在这种情况下,重命名为get1
将导致编译器错误):
#包括
结构开放式{
void get(){
谢谢,关于我的第二个问题。当未实现get
时是否可能抛出编译器错误?类似于重写的东西?如何使void get()生效
virtual如果我想要静态多态性?@MaikKlein那么你必须使用模板机制静态检查给定类型中是否存在get
。检查。@quantdev:Or,(我最喜欢的)给呈现程序成员稍微不同的名称。例如void renderer::get(){static_cast(this)->get()}
,如果函数未在派生类中正确实现,则始终会出现编译器错误。@quantdev我不确定最佳做法是什么。我可能会将模板与ducktyping一起使用,也可能会执行assertstatic\u assert(is\u renderer,“”)
或者我用继承和CRTP来解决这个问题。我将为此创建另一个问题。还有…混合n匹配!
void get1() override { ... } // Compiler error
void get() override { ... } // Ok
#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);
}