10

CRTP を使用してコンパイル時のポリモーフィズムを実装しようとしていますが、派生クラスに強制的に関数を実装させたいと考えています。

現在の実装はこのようなものです。

template <class Derived>
struct base {
    void f() {
        static_cast<Derived*>(this)->f();
    }
};

struct derived : base<derived>
{
    void f() {
    ...
    }
};

この実装では、派生クラスが を実装していない場合、関数の呼び出しは無限ループに陥りますf()

派生クラスに強制的に純粋仮想関数のような関数を実装させるにはどうすればよいですか? 「static_assert」のように使用しようとしましstatic_assert(&base::f != &Derived::f, "...")たが、異なるクラスのメンバー関数を指す 2 つのメンバー関数ポインターが比較できないというエラー メッセージが生成されます。

4

3 に答える 3

3
template<typename Derived>
class Base
{
  private:
    static void verify(void (Derived::*)()) {}

  public:
    void f()
    {
        verify(&Derived::f);
        static_cast<Derived*>(this)->f();
    }
};

f派生クラスが独自に実装しない場合、 の型は&Derived::fになりvoid (Base::*)()、コンパイルが中断されます。

C++11 以降、可変個引数テンプレートを使用してこの関数をジェネリックにすることもできます。

template<typename Derived>
class Base
{
  private:
    template<typename T, typename...Args>
    static void verify(T (Derived::*)(Args...)) {}
};
于 2016-09-30T09:24:35.437 に答える