Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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+中的静态多态性+; #包括 模板 结构渲染器{ void get(){ 静态_cast(this)->get(); } }; 结构open\u gl:公共渲染器{ void get(){ 标准::cout 因为get未标记const 因为使用了基类方法(与cast无关),它进入无限循环_C++_Polymorphism - Fatal编程技术网

C++ C+中的静态多态性+; #包括 模板 结构渲染器{ void get(){ 静态_cast(this)->get(); } }; 结构open\u gl:公共渲染器{ void get(){ 标准::cout 因为get未标记const 因为使用了基类方法(与cast无关),它进入无限循环

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

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<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)将调用base
get
方法,进入无限递归:堆栈溢出

如果您声明了函数(它需要是虚拟的),如果编译器确实没有重写基方法,它将抛出一个错误:

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一起使用,也可能会执行assert
static\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);
}