簡體   English   中英

我可以使用模板成員函數來替代 CRTP 以實現靜態多態嗎?

[英]Can I use template member functions as an alternative to the CRTP in order to implement static polymorphism?

我想在 C++ 中使用靜態多態來實現模板方法模式。

現在我有兩個非常相似的類AB 它們具有相同的公共 API 和完全相同的私有數據成員列表。 大多數公共成員函數的實現也相同,但對於其中一些,這兩個類的實現略有不同。

情況看起來有點像這樣:

class A {
public:
  /* Ctor etc... */
  int One() const;
  int Two() const;
  int Three() const; /* Calls PrivateA() internally */
private:
  int PrivateA() const;
  int a;
  int b;
  int c;
};

class B {
public:
  /* Ctor etc... */
  int One() const; /* Identical to A::One() */
  int Two() const; /* Identical to A::Two() */
  int Three() const; /* Same as in A::Three() but calls PrivateB() instead of PrivateA() internally */
private:
  int PrivateB() const; /* Specific for B */
  /* Identical data members (type and semantics) to A */
  int a;
  int b;
  int c;
};

我現在想通過將所有共享代碼和數據成員移動到基類並從基類內部委托子類特定成員函數來減少代碼重復。 也就是說,像這樣:

class Base {
public:
  int One() const;
  int Two() const;
  int Three() const; /* Should delegate to Private() internally */
private:
  int a;
  int b;
  int c;
};

class A : public Base {
private:
  int Private() const;
};

class B : public Base {
private:
  int Private() const;
};

我知道我可以以類似於以下的方式使用CRTP解決這個問題:

template<typename T>
class Base {
public:
  int One() const;
  int Two() const;
  int Three() const; /* Should delegate to Private() internally */
private:
  int a;
  int b;
  int c;
};

class A : public Base<A> {
private:
  friend class Base<A>;
  int Private() const;
  int p;
};

class B : public Base<B> {
private:
  friend class Base<B>
  int Private() const;
  int q;
};

template<typename T>
int Base<T>::Three() const {
  return static_cast<const T*>(this)->Private();
}

int A::Private() const { return this->p; }
int B::Private() const { return this->q; }

int main() {
  A a{};
  B b{};

  /* Uses shared code from base class */
  a.One();
  b.One();

  /* Base class code statically dispatches to sub-class code via CRTP */
  a.Three(); /* Returns value of p */
  b.Three(); /* Returns value of q */

  return 0;
}

現在開始我的問題。

是否可以在使Base成為模板類的情況下獲得相同的結果? 我可以使用例如模板成員函數來完成同樣的事情嗎?

/* Note: no template */
class Base {
public:
  int One() const;
  int Two() const;

  template<typename T>
  int Three() const; /* Should delegate to Private() internally */
private:
  int a;
  int b;
  int c;
};

如果問題嚴格來說是“我可以” - 答案是“是的,你可以,非常簡單”:

template<typename T>
int Three() const {
    return static_cast<const T*>(this)->Private();
}
    

但是,我不建議這樣做,因為 CRTP 的好處之一是(幾乎)不可能濫用static_cast - static_cast幾乎總是有效的。

使用上面顯示的片段,人們很容易犯錯誤並提供錯誤的模板參數,並使static_cast行為未定義。

結論 - 使用這種方法沒有任何好處,但可以找到一個缺點。

暫無
暫無

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

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