确保从父CRTP类派生的类实现函数

use*_*401 10 c++ crtp c++11

简要:

我想确保派生类实现父CRTP类中的函数所需的成员函数.

详情:

我有一些像这样的代码

class Base
{
public:
    class Params
    {
    public:
        virtual ~Params() {}
    };

    virtual void myFunc( Params& p ) = 0;
};

template< typename T >
class CRTP : public Base
{
public:
    virtual void myFunc( Base::Params& p ) override
    {
        typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
        static_cast<T*>( this )->myFunc( typeParams );
    }

};

class Imp : public CRTP<Imp>
{
public:
    class Params : public CRTP<Imp>::Params
    {
    public:
        virtual ~Params() {}

        int x, y, z;
    };

    virtual void myFunc( Imp::Params& p );
};
Run Code Online (Sandbox Code Playgroud)

目的是我可以让多个Imp子类都做不同的事情myFunc并接受他们自己需要的参数.然后提供的接口Base由更高级别的函数使用,这些函数只需要具有类型Base::Params和的指针/引用Base.我的问题是确保任何Imp提供专业myFunc.要避免无限递归Imp必须实现myFunc.

我的第一次尝试是添加一个纯虚函数 CRTP

virtual void myFunc( typename T::Params& p ) = 0;
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为Imp在定义时尚未完全CRTP定义.这个问题使用了一个static_assert让我想到与static_assert内部做同样的事情CRTP::myFunc.除了我不确定静态断言中非静态函数的表达式应该是什么.

  1. 我可以用static_assert我需要的东西吗?
  2. 这是确保派生类具有所需功能的最佳/最干净的方法吗?
  3. 我是否因为课堂设计而感到厌烦,还有更好的做事方式?

谢谢.

Rud*_*lis 6

为什么不为函数使用不同的名称?然后,对于CRTP没有和实现的每个类的派生,您将有一个编译错误.考虑一下:

class Base
{
public:
    class Params
    {
    public:
        virtual ~Params() {}
    };

    virtual void myFunc( Params& p ) = 0;
};

template< typename T >
class CRTP : public Base
{
public:
    virtual void myFunc( Base::Params& p ) final override
    {
        typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
        static_cast<const T*>( this )->myFuncImp( typedParams );
    }

};

class Imp : public CRTP<Imp>
{
public:
    class Params : public CRTP<Imp>::Params
    {
    public:
        virtual ~Params() {}

        int x, y, z;
    };
};

int main(int argc, char** argv)
{
    Imp imp;
}
Run Code Online (Sandbox Code Playgroud)

编译失败,因为没有myFuncImp提供Imp.

  • 在`CRTP`中添加`final`到`myFunc`以避免混淆. (2认同)