การตีความ static_cast“ static_cast <void (Pet :: *) (int)>” syntax?

Nov 01 2020

ฉันพยายามที่จะเข้าใจความหล่อคงที่ที่ใช้ในเอกสาร Pybind11 ที่นี่ โดยเฉพาะพวกเขาใช้ไวยากรณ์

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

เนื่องจากฉันไม่เคยเห็นไวยากรณ์นี้มาก่อนที่ฉันจะจัดโครงสร้างเพื่อตีความและนำไปใช้กับโค้ดของฉันเองดังนั้นฉันจึงหวังว่าจะมีใครอธิบายได้ว่าเกิดอะไรขึ้น ขอบคุณ

แก้ไข - บริบทบางอย่าง

ฉันกำลังสร้างการเชื่อม Pybind11 กับเมธอดที่โอเวอร์โหลดซึ่งมีลายเซ็นสองแบบซึ่งแตกต่างกันตามconstคุณสมบัติเท่านั้น คลาสที่ฉันผูกเป็นเทมเพลตดังนั้นฉันจึงใช้กลยุทธ์นี้เพื่อสร้างการเชื่อมโยง

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

    ...

ฟังก์ชันตัวช่วยเวอร์ชันของฉันที่อธิบายไว้ในโพสต์นั้นคือ:

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

แต่getRowNamesบรรทัดสร้างข้อผิดพลาดต่อไปนี้:

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

สำหรับใครก็ตามที่อ่านสิ่งนี้นักแสดงที่ฉันสามารถเข้าใจได้ต้องขอบคุณคำตอบคือ:

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

คำตอบ

3 CasperDijkstra Nov 01 2020 at 21:05

ความหมายของ:

static_cast<void (Pet::*)(int)>(&Pet::set)
  • static_cast<T_1>(T_2) หมายความว่าเรากำลังคัดเลือกประเภท 2 เป็นประเภท 1
  • T_1:
    • (Pet::*)เป็นตัวชี้ไปยังสมาชิกชั้นเรียนของสัตว์เลี้ยง (ดูhttps://stackoverflow.com/a/9939367/14344821 สำหรับการอภิปรายเพิ่มเติม)
    • void (Pet::*)(int)เป็นตัวชี้ไปยังฟังก์ชันสมาชิกที่รับintพารามิเตอร์ส่งคืน avoid
  • T_2
    • &Pet::set คือตำแหน่งหน่วยความจำของ Pet::set

ดังนั้นโดยทั่วไปเราจะระบุอย่างชัดเจนว่าเราจะกำหนดค่าจำนวนเต็ม

ตอนนี้เราสามารถผูกsetฟังก์ชันsกับ python ได้แล้ว (อนุญาตให้เราตั้งค่าทั้งอายุและชื่อ):

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