How to avoid errors while using CRTP?

狂风中的少年 提交于 2019-11-27 08:54:33

In C++0x you have a simple solution. I don't know whether it is implemented in MSVC10 however.

template <typename T>
struct base
{
private:
    ~base() {}
    friend T;
};

// Doesn't compile (base class destructor is private)
struct foo : base<bar> { ... };

You can use something like this:

template<class T> class Base {
protected:
   // derived classes must call this constructor
   Base(T *self) { }
};

class Foo : public Base<Foo> {
public:
   // OK: Foo derives from Base<Foo>
   Foo() : Base<Foo>(this) { }
};

class Moo : public Base<Foo> {
public:
   // error: constructor doesn't accept Moo*
   Moo() : Base<Foo>(this) { }
};

class Bar : public Base<Foo> {
public:
   // error: type 'Base<Bar>' is not a direct base of 'Bar'
   Bar() : Base<Bar>(this) { }
};
Abyx
template<typename T, int arg1, int arg2>
struct Base
{
    typedef T derived_t;
};

struct Foo : Base<Foo, 1, 2>
{
    void check_base() { Base::derived_t(*this); } // OK
};

struct Bar : Base<Foo, 1, 2>
{
    void check_base() { Base::derived_t(*this); } // error
};

This code is based on Amnon's answer, but checking code don't contains name of derived class, so I can copy and paste it without changes.

There's no way of knowing the deriving type. You could enforce that Foo derived from Base<Foo>, but you can't enforce that no other classes also derive from that.

I can use a macro

#define SOMENAMESPACE_BASE(type, arg1, arg2) type : Base<type, arg1, arg2>

but I don't want to use macros if better solution exists.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!