如何在C++中强制使用奇怪的重复模板模式

Hot*_*PxL 7 c++ inheritance templates crtp

我有以下基本模板类.

template<typename T>
class Base {
  public:
    void do_something() {
    }
};
Run Code Online (Sandbox Code Playgroud)

它旨在用作奇怪的重复模板模式.它应该是继承的class B : public Base<B>.它不能像继承一样继承class B : public Base<SomeoneElse>.我想静态地执行这个要求.如果有人使用了这个错误,我预计编译阶段会出错.

我正在做的是把一个static_cast<T const&>(*this)do_something().这样,继承模板的类是继承自作为模板参数提供的类.抱歉这个令人困惑的表情.用简单的英语,它需要B是或继承SomeoneElseclass B : public Base<SomeoneElse>.

我不知道这是否是实现这一目标的最佳方式.看起来很粗鲁.

但是我想做更多.我想确保BSomeoneElse本身.我怎样才能做到这一点?

T.C*_*.C. 8

使构造函数(或析构函数)为Baseprivate,然后创建T一个friend.这样,构建/破坏a的唯一方法Base<T>就是a T.


Dan*_*ker 5

如果您的类包含一些代码:

T* pT = 0;
Base *pB = pT;
Run Code Online (Sandbox Code Playgroud)

T如果与赋值不兼容,则会出现编译器错误Base

这种检查在 C++11 中得到了形式化,因此您不必手动编写它,并且可以获得有用的错误消息:

#include <type_traits>

template<typename T>
class Base {

public:
    void do_something() 
    {
        static_assert(
            std::is_base_of<Base, T>::value,
            "T must be derived from Base");
    }
};

class B : public Base<B> { };

int main()
{
    B b;
    b.do_something();
}
Run Code Online (Sandbox Code Playgroud)

至于确保 的Base类型参数正是从它派生的类,这在概念上似乎是有缺陷的。充当基类的类无法“谈论”继承它的类型。它可能通过多重继承被多次继承,或者根本不被继承。