¿Interpretando la sintaxis de static_cast “static_cast <void (Pet :: *) (int)>”?
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
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 unintparámetro, devolviendo unvoid
T_2&Pet::setes la ubicación de la memoria dePet::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");