首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >什么是奇怪的循环模板模式(CRTP)?

什么是奇怪的循环模板模式(CRTP)?
EN

Stack Overflow用户
提问于 2010-11-13 23:30:08
回答 3查看 53.8K关注 0票数 216

在不参考书籍的情况下,有没有人能用代码示例为CRTP提供一个很好的解释?

EN

回答 3

Stack Overflow用户

发布于 2014-11-04 00:42:08

在这里你可以看到一个很好的例子。如果你使用虚拟方法,程序将知道在运行时执行什么。实现CRTP编译器是在编译时决定的!这是一场伟大的表演!

代码语言:javascript
复制
template <class T>
class Writer
{
  public:
    Writer()  { }
    ~Writer()  { }

    void write(const char* str) const
    {
      static_cast<const T*>(this)->writeImpl(str); //here the magic is!!!
    }
};


class FileWriter : public Writer<FileWriter>
{
  public:
    FileWriter(FILE* aFile) { mFile = aFile; }
    ~FileWriter() { fclose(mFile); }

    //here comes the implementation of the write method on the subclass
    void writeImpl(const char* str) const
    {
       fprintf(mFile, "%s\n", str);
    }

  private:
    FILE* mFile;
};


class ConsoleWriter : public Writer<ConsoleWriter>
{
  public:
    ConsoleWriter() { }
    ~ConsoleWriter() { }

    void writeImpl(const char* str) const
    {
      printf("%s\n", str);
    }
};
票数 54
EN

Stack Overflow用户

发布于 2018-03-10 03:14:08

CRTP是一种实现编译时多态性的技术。这里有一个非常简单的例子。在下面的示例中,ProcessFoo()使用Base类接口,Base::Foo调用派生对象的foo()方法,这就是您打算对虚方法执行的操作。

http://coliru.stacked-crooked.com/a/2d27f1e09d567d0e

代码语言:javascript
复制
template <typename T>
struct Base {
  void foo() {
    (static_cast<T*>(this))->foo();
  }
};

struct Derived : public Base<Derived> {
  void foo() {
    cout << "derived foo" << endl;
  }
};

struct AnotherDerived : public Base<AnotherDerived> {
  void foo() {
    cout << "AnotherDerived foo" << endl;
  }
};

template<typename T>
void ProcessFoo(Base<T>* b) {
  b->foo();
}


int main()
{
    Derived d1;
    AnotherDerived d2;
    ProcessFoo(&d1);
    ProcessFoo(&d2);
    return 0;
}

输出:

代码语言:javascript
复制
derived foo
AnotherDerived foo
票数 33
EN

Stack Overflow用户

发布于 2013-10-11 14:13:57

如上所述:

CRTP可以用来实现静态多态性(类似于动态多态性,但没有虚函数指针表)。

代码语言:javascript
复制
#pragma once
#include <iostream>
template <typename T>
class Base
{
    public:
        void method() {
            static_cast<T*>(this)->method();
        }
};

class Derived1 : public Base<Derived1>
{
    public:
        void method() {
            std::cout << "Derived1 method" << std::endl;
        }
};


class Derived2 : public Base<Derived2>
{
    public:
        void method() {
            std::cout << "Derived2 method" << std::endl;
        }
};


#include "crtp.h"
int main()
{
    Derived1 d1;
    Derived2 d2;
    d1.method();
    d2.method();
    return 0;
}

输出将为:

代码语言:javascript
复制
Derived1 method
Derived2 method
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4173254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档