SIP: Virtual pure method with std::function
    Julien Cabieces 
    julien.cabieces at oslandia.com
       
    Thu Apr  1 10:58:27 BST 2021
    
    
  
Hi,
I would like to define an interface (abstract class) where one method is
pure virtual and takes a std::function as a parameter.
I have this in my C++ header
```
class MyInterface
{
  public:
#ifndef SIP_RUN
    virtual MyObject *doThings( const QString &filePath, const QUrl &url,
                                const std::function<void ( const QString & )> &errorCallback = {} ) = 0 ;
#else
    virtual MyObject *doThings( const QString &filePath, const QUrl &url, SIP_PYCALLABLE / AllowNone / ) = 0;
    % MethodCode
    {
      Py_BEGIN_ALLOW_THREADS
      sipCpp->MyInterface::doThings( *a0, *a1, [a2]( const QString  & error )
      {
        SIP_BLOCK_THREADS
        Py_XDECREF( sipCallMethod( NULL, a2, "D", &error, sipType_QString, NULL ) );
        SIP_UNBLOCK_THREADS
      } );
      sipRes = sipCpp;
      Py_END_ALLOW_THREADS
    }
    % End
#endif
```
and this in the corresponding sip file
```
class MyInterface
{
%TypeHeaderCode
#include "myinterface.h"
%End
  public:
    virtual MyObject *doThings( const QString &filePath, const QUrl &url, SIP_PYCALLABLE / AllowNone / ) = 0;
%MethodCode
    {
      Py_BEGIN_ALLOW_THREADS
      sipCpp->MyInterface::doThings( *a0, *a1, [a2]( const QString  & error )
      {
        SIP_BLOCK_THREADS
        Py_XDECREF( sipCallMethod( NULL, a2, "D", &error, sipType_QString, NULL ) );
        SIP_UNBLOCK_THREADS
      } );
      sipRes = sipCpp;
      Py_END_ALLOW_THREADS
    }
%End
};
```
I end up with the following compilation errors
```
error: non-virtual member function marked 'override' hides virtual member function
     ::MyObject* doThings(const  ::QString&,const  ::QUrl&,PyObject *) SIP_OVERRIDE;
hidden overloaded virtual function 'MyInterface::doThings' declared here: type mismatch at 3rd parameter ('const std::function<void (const QString &)> &' vs 'PyObject *' (aka '_object *'))
           virtual MyObject *doThings( const QString &filePath, const QUrl &url,
                     ^
 error: allocating an object of abstract class type 'sipMyInterface'
            sipCpp = new sipMyInterface();
                         ^
note: unimplemented pure virtual method 'doThings' in 'sipMyInterface'
    virtual MyObject *doThings( const QString &filePath, const QUrl &url,
```
The errors make sense to me because the sip doThings version has not the
same signature than the original Cpp one (Callable vs std::function) but
I fail to understand how to fix this.
Kind regards,
Julien
    
    
More information about the PyQt
mailing list