invalid abstract return type when wrapping operator overloading on an abstract base class
Open
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Issue description
It appears that execute_cast in pybind11's operators.h introduces an artificial requirement that the wrapped type be concrete and copyable (because execute_cast returns a plain instance).
pybind11/include/pybind11/operators.h:84:14: error: invalid abstract return type ‘Abstract’
static B execute_cast(const L &l, const R &r) { return B(expr); } \
Reproducible example code
#include <pybind11/pybind11.h>
#include <pybind11/operators.h>
class Abstract
{
bool operator==(const Abstract &other) const
{
return true;
}
virtual void doit() = 0;
};
class Concrete : public Abstract
{
virtual void doit()
{
}
};
namespace py = pybind11;
PYBIND11_MODULE(mod, m)
{
py::class_<Abstract>(m, "Abstract")
.def(py::self == py::self)
;
}
compiled with
c++ -Ipybind11/include -I/usr/include/python3.6 t.cpp
gives
In file included from t.cpp:2:
pybind11/include/pybind11/operators.h: In instantiation of ‘struct pybind11::detail::op_impl<(pybind11::detail::op_id)25, (pybind11::detail::op_type)0, Abstract, Abstract, Abstract>’:
pybind11/include/pybind11/operators.h:59:24: required from ‘void pybind11::detail::op_<id, ot, L, R>::execute(Class&, const Extra& ...) const [with Class = pybind11::class_<Abstract>; Extra = {}; pybind11::detail::op_id id = (pybind11::detail::op_id)25; pybind11::detail::op_type ot = (pybind11::detail::op_type)0; L = pybind11::detail::self_t; R = pybind11::detail::self_t]’
pybind11/include/pybind11/pybind11.h:1103:9: required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def(const pybind11::detail::op_<id, ot, L, R>&, const Extra& ...) [with pybind11::detail::op_id id = (pybind11::detail::op_id)25; pybind11::detail::op_type ot = (pybind11::detail::op_type)0; L = pybind11::detail::self_t; R = pybind11::detail::self_t; Extra = {}; type_ = Abstract; options = {}]’
t.cpp:25:30: required from here
pybind11/include/pybind11/operators.h:130:67: error: ‘bool Abstract::operator==(const Abstract&) const’ is private within this context
PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)
~~^~~~
pybind11/include/pybind11/operators.h:83:61: note: in definition of macro ‘PYBIND11_BINARY_OPERATOR’
static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \
^~~~
t.cpp:6:8: note: declared private here
bool operator==(const Abstract &other) const
^~~~~~~~
In file included from t.cpp:2:
pybind11/include/pybind11/operators.h:84:14: error: invalid abstract return type ‘Abstract’
static B execute_cast(const L &l, const R &r) { return B(expr); } \
^~~~~~~~~~~~
pybind11/include/pybind11/operators.h:130:1: note: in expansion of macro ‘PYBIND11_BINARY_OPERATOR’
PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)
^~~~~~~~~~~~~~~~~~~~~~~~
t.cpp:4:7: note: because the following virtual functions are pure within ‘Abstract’:
class Abstract
^~~~~~~~
t.cpp:10:16: note: ‘virtual void Abstract::doit()’
virtual void doit() = 0;
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pybind11/include/pybind11/operators.h, especially execute_cast and the operator implementation used by .def(py::self == py::self). Compile the provided abstract-class example first, then inspect existing operator tests for comparable coverage. Done means the example no longer requires an invalid abstract return type when wrapping the operator.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100