Interpretazione della sintassi static_cast "static_cast <void (Pet :: *) (int)>"?

Nov 01 2020

Sto cercando di capire il cast statico usato nei documenti di Pybind11 qui . In particolare, usano la sintassi

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

Dato che non ho visto questa sintassi prima, mi sforzo di interpretare e applicare il mio codice, quindi speravo che qualcuno potesse spiegare cosa sta succedendo qui. Grazie

Modifica: un po 'di contesto

Sto creando associazioni Pybind11 a un metodo sovraccarico che ha due firme, che differiscono solo per constqualifica. La classe che sto associando è un modello, quindi sto usando questa strategia per creare le associazioni

    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;
        }

    ...

La mia versione della funzione di supporto descritta in quel post è questa:

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))

ma la getRowNamesriga produce il seguente errore:

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

Per chiunque altro abbia letto questo, il cast che sono riuscito a capire grazie alla risposta è:

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

Risposte

3 CasperDijkstra Nov 01 2020 at 21:05

Il significato di:

static_cast<void (Pet::*)(int)>(&Pet::set)
  • static_cast<T_1>(T_2) significa che stiamo trasmettendo il tipo 2 al tipo 1.
  • T_1:
    • (Pet::*)è un puntatore a un membro della classe di Pet (vederehttps://stackoverflow.com/a/9939367/14344821 per un'ulteriore discussione)
    • void (Pet::*)(int)è un puntatore a una funzione membro che accetta un intparametro, restituendo un filevoid
  • T_2
    • &Pet::set è la posizione di memoria di Pet::set

Quindi, in pratica, stiamo affermando esplicitamente che stiamo impostando il valore intero .

Ora possiamo associare la setfunzione s a python (permettendoci di impostare sia l'età che il nome):

   .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");