簡體   English   中英

Concept-ed 與 CRTP 靜態/編譯時多態性 - 使用基本 class 方法和來自派生 class 的變量

[英]Concept-ed vs CRTP static/compile-time polymorphism - using base class methods and variables from derived class

我一直在學習 c++20 概念作為 static 多態性 CRTP 模板設計的替代方案(對於那些不知道我在說什么的人,這里有一個很好的資源: https://www.fluentcpp.com /2020/09/11/replacing-crtp-static-polymorphism-with-concepts/ )

CRTP 的好處是您可以在基類 class 中有一個變量並在子類中使用它。 這是一個工作示例,其中shared是共享變量。 按照同樣的邏輯,我們可以在派生的 class 中調用基類 class 的構造函數和方法。

template <class TImpl>
class Base {
private:
  TImpl &impl = static_cast<TImpl &>(*this);
  friend TImpl;
  int shared = 0;

public:
  void say_hello() { impl.do_say_hello(); }
};

class Derived : public Base<Derived> {
  friend Base<Derived>;
  void do_say_hello() {
    shared = 3;
    cout << "Hello " << shared << endl;
  }
};

int main() {
  Derived d;
  d.say_hello();
}

然而,這是我陷入 c++ 20 個概念的地方。 我可以輕松地從基類 class 調用派生的 class 方法,但反之則不行,感覺有點像反向多態。 有誰知道我如何調用基數 class 方法並在派生的 class 中使用基數 class 的變量和 Concept-ed static 多態性?

CRTP 是一個 C++ 工具,用於在 C++ 中實現mixin的概念。mixin 是一種將一些通用功能注入到特定類型的接口中的方法。 因此,這涉及兩段獨立的代碼:通用功能和注入此功能的接口。

這篇文章有效地提出了一種通過自由函數進行混合的方法。 這篇文章本質上是在實現一種蹩腳的定制點習語形式(然后將其呈現為一種發現,而不僅僅是基於conceptstd::begin版本。你知道,就像std::ranges::begin )。

自定義點在通信方面通常是單向街道。 通用定制點 function 可以檢查它正在擴充的接口,但該接口本身不能與通用功能交互。 至少,不是輕易也不是以非公開的方式。

相比之下,CRTP 允許簡單的雙向通信。 通用功能(模板基類)可以通過將this轉換為模板參數來調用派生的 class 函數( C++23 使這種方式更容易)。 並且由於是派生的 class,被注入的 class 可以與基 class 通信,如果基 class 為此目的公開protected的接口成員。

文章提出的中間形式(其中泛型功能是派生的 class,注入的目標是基類)也主要是單向的:generic-to-target。 CRTP 轉換之所以有效,是因為基礎 class 被賦予派生的 class 類型。 模板實例化規則允許以某些方式使用派生的 class 類型,盡管該類型在 inheritance 點不完整。

因此,當您將基數設為非模板 class 時,沒有給出派生的 class 名稱,您就切斷了它執行轉換技巧的能力。 這意味着像這樣反轉層次結構會使 mixin 通信成為單向的。 盡管該 C++23 技巧確實允許您重新獲得雙向通信。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM