Можете ли вы использовать CRTP и функции, используя интерфейс в качестве параметра? - PullRequest
2 голосов
/ 16 февраля 2012

В C ++ чисто виртуальные классы часто используются для полиморфизма во время выполнения.

Итак, у вас есть:

class IInterfaceA
{
    virtual void DoFoo() = 0;
};

И производные классы, такие как:

class CFancyObject : public IInterfaceA
{
...

Какие тогдаможет использоваться в таких функциях, как:

void Foo(IInterfaceA &interface);

Но это случай выполнения, и если объекты известны во время компиляции, мы можем добиться большего успеха, используя CRTP:

template<class T> class IInterfaceA
{
public:
    void DoFoo()
    {    
        static_cast<T*>(this)->CallDerivedFunction();
    }
}

class CFancyObject : public IInterfaceA<CFancyObject>
{
    ...
}

Isможно использовать производные классы на основе CRTP в функциях, которые принимают IInterface в качестве параметра?

void Foo(IInterfaceA<?> &interface);

Ответы [ 2 ]

2 голосов
/ 16 февраля 2012

Интерфейс предназначен для отделения API класса от его реализации. Вводя параметр шаблона, вы тесно связываете реализацию с интерфейсом, разбивая всю цель. CRTP предназначен для решения другого набора проблем.

Если вы сделаете интерфейс шаблонным, функция, принимающая его в качестве параметра, также должна быть шаблонной. Как только вы это сделаете, нет никакой разницы между использованием класса интерфейса и использованием класса реализации.

template<class T>
void Foo(IInterfaceA<T> &interface) { interface.DoFoo(); }

идентичен и не дает никаких преимуществ перед

template<class T>
void Foo(T &object) { object.DoFoo(); }
0 голосов
/ 16 февраля 2012

Не могли бы вы просто сделать:

template<class T> class IInterfaceA 
{
public:
    template<class T2>
    void DoFoo(IInterfaceA<T2> &interface)
    {    
        static_cast<T*>(this)->CallDerivedFunction(interface);
    }
}

class CFancyObject : public IInterfaceA<CFancyObject>
{
    template<class T2>
    CallDerivedFunction(IInterfaceA<T2> &interface) {...}
}

...