微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以使用模板成员函数来替代 CRTP 以实现静态多态吗?

如何解决我可以使用模板成员函数来替代 CRTP 以实现静态多态吗?

我想在 C++ 中使用静态多态实现 template method 模式。

现在我有两个非常相似的类 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 未定义行为。

结论 - 使用这种方法没有任何好处,但可以找到一个缺点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。