c++ - 确保从父 CRTP 类派生的类实现功能

标签 c++ c++11 crtp

简介:

我想确保派生类实现父 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 );
};

我的目的是让多个 Imp 子类都在 myFunc 中做不同的事情并接受它们自己需要的参数。 Base 提供的接口(interface)随后由更高级别的函数使用,这些函数只需要具有 Base::ParamsBase 类型的指针/引用.我的问题是确保任何 Imp 都提供专门的 myFunc。为了避免无限递归,Imp 必须实现 myFunc

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

virtual void myFunc( typename T::Params& p ) = 0;

但这不起作用,因为在定义 CRTPImp 尚未完全定义。 This question使用 static_assert 这让我想到了对 CRTP::myFunc 中的 static_assert 做同样的事情。除了我不确定非静态函数的静态断言中的表达式应该是什么。

  1. 我可以使用 static_assert 来满足我的需要吗?
  2. 这是确保派生类具有所需功能的最好/最干净的方法吗?
  3. 我是否对我的类(class)设计着了迷并且有更好的做事方式?

谢谢。

最佳答案

为什么不为函数使用不同的名称?然后,对于没有实现的 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;
}

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

关于c++ - 确保从父 CRTP 类派生的类实现功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32354501/

相关文章:

c++ - 将所有权从 unique_ptr<T,void(*)(T*)> 转移到 unique_ptr<const T,void(*)(const T*)>

c++ - 绑定(bind)到可变成员函数

c++ - CRTP 和表达式模板 线性代数

c++ - 制作预编译代码/数据结构

c++ - 从字符串中提取值 C++

c++ - 避免在树结构中使用强制转换

c++ - 如何修复从 poco 库收到的异常?

c++ - 指向模板类重载方法的指针

c++ - 嵌套类对象的工作?

c++ - 缩短作为模板参数传递到 CRTP ("pass me"中的长模板派生类)