I'm trying to understand the static cast as used in the Pybind11 docs here. Specifically, they use the syntax
static_cast<void (Pet::*)(int)>(&Pet::set)
Since I haven't seen this syntax before I'm strugling to interpret and apply to my own code so I was hoping somebody could explain what's going on here. Thanks
I am creating Pybind11 bindings to an overloaded method that has two signatures, which only differ by const qualification. The class I am binding is a template so I am using this strategy to create the bindings
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;
}
...
My version of the helper function described in that post is this:
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))
but the getRowNames line produces the following error:
Address of overloaded function 'getRowNames' cannot be static_cast to type 'const std::vector<std::string> (ls::Matrix<complex<double>>::*)()'
For anybody else reading this, the cast I was able to figure out thanks to the answer is:
static_cast< std::vector<std::string>& (ls::Matrix<T>::*)()>(&Class::getRowNames)
The meaning of:
static_cast<void (Pet::*)(int)>(&Pet::set)
static_cast<T_1>(T_2) means we're casting type 2 to type 1.T_1:
(Pet::*) is a pointer to a class member of Pet (see https://stackoverflow.com/a/9939367/14344821 for a further discussion)void (Pet::*)(int) is a pointer to a member function that takes an int parameter, returning a voidT_2
&Pet::set is the memory location of Pet::setSo basically, we're stating explicitly that we are setting the integer value.
Now we can bind the set functions to python (allowing us to set both age and name):
.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");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With