Interpretando a sintaxe de static_cast “static_cast <void (Pet :: *) (int)>”?

Nov 01 2020

Estou tentando entender o elenco estático usado nos documentos do Pybind11 aqui . Especificamente, eles usam a sintaxe

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

Como não vi essa sintaxe antes, estou lutando para interpretar e aplicar ao meu próprio código, então esperava que alguém pudesse explicar o que está acontecendo aqui. obrigado

Editar - algum contexto

Estou criando associações Pybind11 para um método sobrecarregado que tem duas assinaturas, que diferem apenas pela constqualificação. A classe que estou vinculando é um modelo, então estou usando essa estratégia para criar as vinculações

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

    ...

Minha versão da função auxiliar descrita nessa postagem é esta:

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

mas a getRowNameslinha produz o seguinte erro:

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

Para qualquer pessoa que esteja lendo isso, o elenco que fui capaz de descobrir graças à resposta é:

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

Respostas

3 CasperDijkstra Nov 01 2020 at 21:05

O significado de:

static_cast<void (Pet::*)(int)>(&Pet::set)
  • static_cast<T_1>(T_2) significa que estamos convertendo o tipo 2 para o tipo 1.
  • T_1:
    • (Pet::*)é um indicador para um membro da classe de Pet (vejahttps://stackoverflow.com/a/9939367/14344821 para uma discussão posterior)
    • void (Pet::*)(int)é um ponteiro para uma função de membro que recebe um intparâmetro, retornando umvoid
  • T_2
    • &Pet::set é a localização da memória de Pet::set

Então, basicamente, estamos declarando explicitamente que estamos definindo o valor inteiro .

Agora podemos vincular a setfunção s a python (permitindo definir idade e 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");