¿Interpretando la sintaxis de static_cast “static_cast <void (Pet :: *) (int)>”?

Nov 01 2020

Estoy tratando de comprender la transmisión estática como se usa en los documentos de Pybind11 aquí . Específicamente, usan la sintaxis

static_cast<void (Pet::*)(int)>(&Pet::set)

Como no he visto esta sintaxis antes, estoy luchando por interpretar y aplicar a mi propio código, así que esperaba que alguien pudiera explicar lo que está sucediendo aquí. Gracias

Editar - algo de contexto

Estoy creando enlaces Pybind11 a un método sobrecargado que tiene dos firmas, que solo se diferencian por la constcalificación. La clase que estoy vinculando es una plantilla, así que estoy usando esta estrategia para crear las vinculaciones

    template<class T>
    class Matrix {
    public:

        ...

        /**
         * get the row names
         */
        std::vector<std::string> &getRowNames() {
            return rowNames;
        }

        /**
         * get the row names (mutable)
         */
        const std::vector<std::string> &getRowNames() {
            return rowNames;
        }

    ...

Mi versión de la función auxiliar descrita en esa publicación es la siguiente:

template<typename T>
void declare_matrix(py::module &m, const std::string &typestr) {
    using Class = ls::Matrix<T>;
    const std::string &pyclass_name = typestr;
    py::class_<Class>(m, pyclass_name.c_str(), py::buffer_protocol(), py::dynamic_attr())
            .def(py::init<unsigned int, unsigned int>())
            .def("getRowNames", static_cast<const std::vector<std::string>(ls::Matrix<T>::*)()>(&ls::Matrix<T>::getRowNames))

pero la getRowNameslínea produce el siguiente error:

Address of overloaded function 'getRowNames' cannot be static_cast to type 'const std::vector<std::string> (ls::Matrix<complex<double>>::*)()'

Para cualquiera que lea esto, el reparto que pude averiguar gracias a la respuesta es:

static_cast< std::vector<std::string>& (ls::Matrix<T>::*)()>(&Class::getRowNames)

Respuestas

3 CasperDijkstra Nov 01 2020 at 21:05

El significado de:

static_cast<void (Pet::*)(int)>(&Pet::set)
  • static_cast<T_1>(T_2) significa que estamos lanzando el tipo 2 al tipo 1.
  • T_1:
    • (Pet::*)es un puntero a un miembro de la clase de Pet (verhttps://stackoverflow.com/a/9939367/14344821 para una discusión adicional)
    • void (Pet::*)(int)es un puntero a una función miembro que toma un intparámetro, devolviendo unvoid
  • T_2
    • &Pet::set es la ubicación de la memoria de Pet::set

Básicamente, estamos declarando explícitamente que estamos estableciendo el valor entero .

Ahora podemos vincular la setfunción s a python (lo que nos permite establecer tanto la edad como el nombre):

   .def("set", static_cast<void (Pet::*)(int)>(&Pet::set), "Set the pet's age")
   .def("set", static_cast<void (Pet::*)(const std::string &)>(&Pet::set), "Set the pet's name");