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