可以使用CRTP和以接口为参数的函数吗

Can you use CRTP and functions taking an interface as a parameter?

本文关键字:参数 函数 接口 CRTP 可以使      更新时间:2023-10-16

在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>
{
    ...
}

在以IInterface为参数的函数中,是否可以使用基于CRTP的派生类?

void Foo(IInterfaceA<?> &interface);

接口用于将类的API与其实现解耦。通过引入模板参数,您将实现与接口紧密耦合,从而破坏了整个目的。CRTP旨在解决一系列不同的问题。

如果将接口模板化,那么将其作为参数的函数也必须模板化。一旦完成了这一点,使用接口类和使用实现类就没有区别了。

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

与相同,没有任何优势

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

你就不能这么做吗:

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) {...}
}