当前位置:  开发笔记 > 编程语言 > 正文

CRTP避免动态多态

如何解决《CRTP避免动态多态》经验,为你挑选了2个好方法。

如何在C++中使用CRTP来避免虚拟成员函数的开销?



1> Dean Michael..:

有两种方法.

第一个是通过静态为类型结构指定接口:

template 
struct base {
  void foo() {
    static_cast(this)->foo();
  };
};

struct my_type : base {
  void foo(); // required to compile.
};

struct your_type : base {
  void foo(); // required to compile.
};

第二个是避免使用引用到基础或指针到基础的习惯用法并在编译时进行连接.使用上面的定义,您可以使用如下所示的模板函数:

template  // T is deduced at compile-time
void bar(base & obj) {
  obj.foo(); // will do static dispatch
}

struct not_derived_from_base { }; // notice, not derived from base

// ...
my_type my_instance;
your_type your_instance;
not_derived_from_base invalid_instance;
bar(my_instance); // will call my_instance.foo()
bar(your_instance); // will call your_instance.foo()
bar(invalid_instance); // compile error, cannot deduce correct overload

因此,在函数中结合结构/接口定义和编译时类型推导允许您进行静态调度而不是动态调度.这是静态多态的本质.


很好的答案
我想强调一下,'not_derived_from_base`不是从`base`派生出来的,也不是从`base`派生出来的......
实际上,my_type/your_type中的foo()声明不是必需的.codepad.org/ylpEm1up(导致堆栈溢出) - 有没有办法在编译时强制执行foo的定义? - 好的,找到了一个解决方案:ideone.com/C6Oz9 - 也许你想在你的答案中纠正这个问题.
你能解释一下在这个例子中使用CRTP的动机是什么吗?如果bar将被定义为模板 void bar(T&obj){obj.foo(); 那么提供foo的任何类都没问题.因此,根据您的示例,看起来CRTP的唯一用途是在编译时指定接口.那是什么意思?

2> fizzer..:

我一直在寻找CRTP的正确讨论.托德Veldhuizen的科学的C++技术是一个很好的资源(1.3)等诸多先进技术,如表情模板.

另外,我发现你可以在Google书籍上阅读Coplien的大部分原创C++ Gems文章.也许情况仍然如此.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有