2016-05-30 3 views
2

Предположим, у меня есть базовый класс, как это:Weird модель наследования

class Abstract { 
    public: 
    /* This type should be the deriver of this class */ 
    virtual DerivedType foo(void) = 0; 
}; 

И я хочу DerivedType быть разными в зависимости от того, кто получает от этого класса. На самом деле я хочу, чтобы DerivedType был типом Derives от Abstract.

Я понимаю, что я мог бы сделать что-то вроде этого:

template<typename der_t> 
class Abstract { 
    public: 
    virtual der_t foo(void) = 0; 
}; 

И тогда он должен быть использован, как это:

class Derived : public virtual Abstract<Derived> { }; 

К сожалению, нет никакого способа, чтобы заставить кого-то передать права введите шаблон. То есть кто-то может сделать это:

class Derived : public virtual Abstract<int> { }; 

Так есть ли лучший способ сделать это, или есть способ заставить кого-то, чтобы пройти в нужном параметре?

+4

То, что вы хотите получить, аналогично [CRTP] (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). У меня нет большого опыта с этим, но, похоже, обычно предполагается, что пользователь поместит правильный параметр шаблона. – user463035818

+0

Почему это * несчастливо *, что пользователь шаблона может передать «неправильный» (я бы сказал, другой) тип? Я нахожу, что он делает шаблон более общим и гибким. Хотя случай, когда требуется другой тип, может быть редкими. – user2079303

+1

Я думаю, вы можете использовать статические утверждения для проверки отношений, но перед добавлением кода, который применяет конкретное использование, я бы подумал, что может быть самым худшим, что может произойти, и если вещь, которая может произойти, возможно, даже будет полезна. – molbdnilo

ответ

2

Обычный трюк для CRTP является иметь частный конструктор, который только прошел в классе может получить доступ через friend директивы:

template <class Derived> 
struct Crtp { 

private: 
    friend Derived; 

    Crtp() = default; 
}; 

Это не идеально, но защищает от ошибок.

Примечание: static_assert ING не является практичным решением, поскольку в то время Crtp инстанциируется Derived еще не завершен, и не могут быть проверены на наличие базовых классов.

+0

'friend Derived;' - отличный трюк, не знал, что вы можете найти параметр шаблона. – Rotem

Смежные вопросы