Pybind11: overload pure vitual function that return std::map

Created on 26 Apr 2020  路  6Comments  路  Source: pybind/pybind11

hello, i try to make a trampoline of a abstract class, but build failed. here is my trampoline code:

class PyParameterOptimizer : public ParameterOptimizer {
        public:
            /* Inherit the constructors */
            using ParameterOptimizer::ParameterOptimizer;

            virtual void onAppend(Express::VARP parameter) override {
                PYBIND11_OVERLOAD_PURE(void, ParameterOptimizer, append, parameter);
            }
            virtual void onRemove(Express::VARP parameter) override {
                PYBIND11_OVERLOAD_PURE(void, ParameterOptimizer, remove, parameter);
            }
            virtual std::map<VARP, VARP> onGetNextParameter(VARP loss) override {
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
            }
        };

it is the onGetNextParameter function, when build, it reports:

error: expected '(' after 'static_cast'
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
                ^
pybind11/pybind11.h:2164:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE'
    PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
    ^
pybind11/pybind11.h:2129:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE_NAME'
    PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
    ^
pybind11/pybind11.h:2092:86: note: expanded from macro 'PYBIND11_OVERLOAD_INT'
        pybind11::function overload = pybind11::get_overload(static_cast<const cname *>(this), name); \
                                                                                     ^
MNN.cc:2447:17: error: expected expression
pybind11/pybind11.h:2164:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE'
    PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
    ^
pybind11/pybind11.h:2129:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE_NAME'
    PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
    ^
pybind11/pybind11.h:2092:87: note: expanded from macro 'PYBIND11_OVERLOAD_INT'
        pybind11::function overload = pybind11::get_overload(static_cast<const cname *>(this), name); \
                                                                                      ^
MNN.cc:2447:82: error: use of undeclared identifier 'compute_info_and_update'
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
                                                                                 ^
MNN.cc:2447:45: error: too few template arguments for class template 'map'
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
                                            ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:898:28: note: template is declared here
class _LIBCPP_TEMPLATE_VIS map
                           ^
MNN.cc:2447:17: error: type name requires a specifier or qualifier
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
                ^
pybind11/pybind11.h:2164:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE'
    PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)

pybind11/pybind11.h:2129:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE_NAME'
    PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
    ^
pybind11/pybind11.h:2099:62: note: expanded from macro 'PYBIND11_OVERLOAD_INT'
            else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
                                                             ^
MNN.cc:2447:17: error: unknown type name 'o'
pybind11/pybind11.h:2164:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE'
    PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
    ^
pybind11/pybind11.h:2129:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE_NAME'
    PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
    ^
pybind11/pybind11.h:2099:73: note: expanded from macro 'PYBIND11_OVERLOAD_INT'
            else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
                                                                        ^
MNN.cc:2447:17: error: definition or redeclaration of 'move' not allowed inside a function
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pybind11/pybind11.h:2164:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE'
    PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pybind11/pybind11.h:2129:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE_NAME'
    PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pybind11/pybind11.h:2099:68: note: expanded from macro 'PYBIND11_OVERLOAD_INT'
            else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
                                                              ~~~~~^
MNN.cc:2447:17: error: a function type is not allowed here
                PYBIND11_OVERLOAD_PURE(std::map<VARP, VARP>, ParameterOptimizer, compute_info_and_update, loss);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pybind11/pybind11.h:2164:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE'
    PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pybind11/pybind11.h:2129:5: note: expanded from macro 'PYBIND11_OVERLOAD_PURE_NAME'
    PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pybind11/pybind11.h:2099:68: note: expanded from macro 'PYBIND11_OVERLOAD_INT'
            else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \

why does this happen? thank you!

Most helpful comment

I figured this out. PYBIND11_OVERLOAD_PURE is a macro and it considers std::map to be two different arguments because of the comma in between them. It sees it as "std::map". Therefore, we need to declare a type alias by using typedef or the 'using' keyword.

typedef std::map varp_map;

and then use varp_map in the binding code instead of std::map.

Hope this helps.

All 6 comments

I face the same issue. Did you get the solution/reason for the error?

I face the same issue. Did you get the solution/reason for the error?

No

I figured this out. PYBIND11_OVERLOAD_PURE is a macro and it considers std::map to be two different arguments because of the comma in between them. It sees it as "std::map". Therefore, we need to declare a type alias by using typedef or the 'using' keyword.

typedef std::map varp_map;

and then use varp_map in the binding code instead of std::map.

Hope this helps.

Thank you! I will try it!

Thank you! I will try it!

I'm assuming it worked, since I believe @priyagupta20 made a correct diagnosis of the issue (thanks, @priyagupta20!) and you didn't reply anymore?

I also encountered this error and scratched my head the whole day.
But after using the fix by @priyagupta20, I can confirm it works. Thank you!

Was this page helpful?
0 / 5 - 0 ratings