CRTP-静态界面中的“抽象”方法

时间:2019-01-10 19:29:14

标签: c++ c++11 crtp

我正在尝试找到某种方法来在基本CRTP类和派生类之间强制执行合同。使用动态多态性时,只需执行以下操作即可:

struct foo{
    virtual bar() = 0;
};

并且编译器将确保方法bar是在派生类中实现的,否则它将给出(或多或少)有意义的错误消息。现在,我可以使用CRTP获得的最好的结果是这样的:

template<class Derived>
struct base {
    void stuff(){
        static_cast<Derived &>(*this).baz();  
    }
};

这将以某种方式强制在派生类中实施baz的实现,但并不太可读,并清除基类和派生类之间的约定。所以我的问题是,有没有办法更好地做到这一点?我知道C ++ 20概念,它们对于这种情况将是完美的解决方案,但是我正在寻找C ++ 11 / C ++ 14解决方案以使其尽可能简洁。

1 个答案:

答案 0 :(得分:2)

由于定义基数时派生类总是不完整,因此我使用的一种解决方案是使用默认的模板参数来延迟“概念检查”实例化:

template<class T>
using has_baz = decltype(std::declval<T&>().baz());

template<class Derived>
struct base{
  template<class T = Derived, has_baz<T>* =nullptr>
  void stuff(){/*...*/}
  };

请注意,c ++ 20概念将无法解决此特殊问题,因此仍然有必要延迟概念检查。好处是编译错误会更清楚。

Demo