How to static_cast a pointer to const member function?

Viewed 164

Surprisingly (embarrassingly?) I cannot get the syntax of the static_const of a const member function right. In short (details below) if the member function is not marked const I use:

static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&)>(&mymodule::Foo::bar)

but marking the member function Foo::bar(...) const the compiler does not know what to do:

error: address of overloaded function 'bar' cannot be static_cast to type 'std::vector<double> (mymodule::Foo::*)(const std::vector<double> &)'

Where should I put the function's constness?

Details

I'm trying to create Python binding for the following module:

namespace mymodule {

class Foo
{
public:

    Foo() = default;

    template <class T>
    T bar(const T& a) const
    {
        T ret = a;
        for (auto& i : ret) {
            i *= 2.0;
        }
        return ret;
    }

    template <class T>
    T bar(const T& a, double f) const
    {
        T ret = a;
        for (auto& i : ret) {
            i *= f;
        }
        return ret;
    }

};

} // namespace mymodule

whereby I write the Python bindings with pybind11:

#include <pybind11/pybind11.h>

namespace py = pybind11;

PYBIND11_MODULE(example, m)
{
    py::class_<mymodule::Foo>(m, "Foo")
        .def(py::init<>())

        .def("bar",
             static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&)>(&mymodule::Foo::bar),
             py::arg("a"))

        .def("bar",
             static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&, double)>(&mymodule::Foo::bar),
             py::arg("a"),
             py::arg("f"));
}

which fails to compile:

.../example.cpp:54:14: error: address of overloaded function 'bar' cannot be static_cast to type 'std::vector<double> (mymodule::Foo::*)(const std::vector<double> &)'
             static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&)>(&mymodule::Foo::bar),
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../example.cpp:19:7: note: candidate function template
    T bar(const T& a) const
      ^
.../example.cpp:29:7: note: candidate function template
    T bar(const T& a, double f) const
      ^
.../example.cpp:58:14: error: address of overloaded function 'bar' cannot be static_cast to type 'std::vector<double> (mymodule::Foo::*)(const std::vector<double> &, double)'
             static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&, double)>(&mymodule::Foo::bar),
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../example.cpp:19:7: note: candidate function template
    T bar(const T& a) const
      ^
.../example.cpp:29:7: note: candidate function template
    T bar(const T& a, double f) const
      ^
2 errors generated.
1 Answers

You should add const at last as:

static_cast<std::vector<double> (mymodule::Foo::*)(const std::vector<double>&) const>(&mymodule::Foo::bar),
//                                                                             ^^^^^
Related