如何使用智能指针对象执行成员函数指针?
How to execute member-function-pointer with a smart pointer object?
我正在尝试使用智能指针实例执行 class 的 member-function
。这个函数的地址是按值传递的,我想通过相应 class.
的智能指针实例来调用它
我已经试过了:
(registerList.*setRegister)();
但它出错了:
no match for ‘operator->*
Register
class成员函数:
uint16_t Registers::getSP()
{
return this->sp;
}
代码片段:
std::unique_ptr<Registers> registerList;
SetRegisteropcodeLdWordRegister(&Registers::getSP)
void opcodeLdWordRegister(uint16_t (*Registers::setRegister)())
{
(registerList.*setRegister)();
}
首先,您显示的代码与错误消息不匹配。对于给定的代码 you should be getting (from clang) following error message
error: left hand operand to .* must be a class compatible with the right hand operand, but is 'std::unique_ptr<Registers>'
(registerList.*setRegister)();
^
这可以通过取消引用指针来解决(就像@Caleth 的回答):
((*registerList).*setRegister)();
现在问题中显示的错误消息:no match for ‘operator->*
应该在您尝试以下语法时出现。(Minimal reproducible code)
(registerList->*setRegister)();
这是因为智能指针没有pointer-to-member access operator defined in the standard. Therefore, you need to go for dereferencing the smart pointer via operator*
or by member function std::unique_ptr::get
,调用了成员函数
使用成员 std::unique_ptr::get
正确的语法是 (See the live demo online)
(registerList.get()->*setRegister)()
话虽这么说,如果您有权访问 c++17 use unified version of function invoker std::invoke
来调用相应实例的成员函数,您就可以忘记 operator->*
的(可能)复杂的语法。
您的代码也有几个问题:
你opcodeLdWordRegister
中的成员函数指针类型是
wrong.It 应该是
return_type(Class_name::* variable_name)(/*parameters_types, if any*/)
以下是固定版本。
#include <functional> // std::invoke
void opcodeLdWordRegister(uint16_t(Registers:: * setRegister)())
// ^^^^^^^^^^^^^^^^^^^^^^^^^ >>> correct syntax
{
std::invoke(setRegister, registerList);
// ^^^^^^^^^^^ member function
// ^^^^^^^^^^^^ instance
}
- 其次,取消引用未初始化的
registerList
指针
会导致UB。
以下是该案例的示范性最小完整示例:(See the live demo online)
#include <iostream>
#include <functional> // std::invoke
#include <memory> // std::unique_ptr
class Registers
{
uint16_t sp{2}; // member initialized with 2
public:
uint16_t getSP() const // function can be marked const as it does not alter the member
{
return this->sp;
}
};
auto registerList = std::make_unique<Registers>(); // initialized the pointer with default object
void opcodeLdWordRegister(uint16_t(Registers::*setRegister)() const)
// ^^^^^^^^^^^^^^^^^^^^^^^^^ correct syntax
{
std::cout << std::invoke(setRegister, registerList);
}
int main()
{
opcodeLdWordRegister(&Registers::getSP);
return 0;
}
输出:
2
如果您没有 std::invoke
,您仍然可以执行它会执行的操作,即取消引用调用站点中的(唯一)指针。
((*registerList).*setRegister)();
我正在尝试使用智能指针实例执行 class 的 member-function
。这个函数的地址是按值传递的,我想通过相应 class.
我已经试过了:
(registerList.*setRegister)();
但它出错了:
no match for ‘operator->*
Register
class成员函数:
uint16_t Registers::getSP()
{
return this->sp;
}
代码片段:
std::unique_ptr<Registers> registerList;
SetRegisteropcodeLdWordRegister(&Registers::getSP)
void opcodeLdWordRegister(uint16_t (*Registers::setRegister)())
{
(registerList.*setRegister)();
}
首先,您显示的代码与错误消息不匹配。对于给定的代码 you should be getting (from clang) following error message
error: left hand operand to .* must be a class compatible with the right hand operand, but is 'std::unique_ptr<Registers>'
(registerList.*setRegister)();
^
这可以通过取消引用指针来解决(就像@Caleth 的回答):
((*registerList).*setRegister)();
现在问题中显示的错误消息:no match for ‘operator->*
应该在您尝试以下语法时出现。(Minimal reproducible code)
(registerList->*setRegister)();
这是因为智能指针没有pointer-to-member access operator defined in the standard. Therefore, you need to go for dereferencing the smart pointer via operator*
or by member function std::unique_ptr::get
,调用了成员函数
使用成员 std::unique_ptr::get
正确的语法是 (See the live demo online)
(registerList.get()->*setRegister)()
话虽这么说,如果您有权访问 c++17 use unified version of function invoker std::invoke
来调用相应实例的成员函数,您就可以忘记 operator->*
的(可能)复杂的语法。
您的代码也有几个问题:
你
opcodeLdWordRegister
中的成员函数指针类型是 wrong.It 应该是return_type(Class_name::* variable_name)(/*parameters_types, if any*/)
以下是固定版本。
#include <functional> // std::invoke void opcodeLdWordRegister(uint16_t(Registers:: * setRegister)()) // ^^^^^^^^^^^^^^^^^^^^^^^^^ >>> correct syntax { std::invoke(setRegister, registerList); // ^^^^^^^^^^^ member function // ^^^^^^^^^^^^ instance }
- 其次,取消引用未初始化的
registerList
指针 会导致UB。
以下是该案例的示范性最小完整示例:(See the live demo online)
#include <iostream>
#include <functional> // std::invoke
#include <memory> // std::unique_ptr
class Registers
{
uint16_t sp{2}; // member initialized with 2
public:
uint16_t getSP() const // function can be marked const as it does not alter the member
{
return this->sp;
}
};
auto registerList = std::make_unique<Registers>(); // initialized the pointer with default object
void opcodeLdWordRegister(uint16_t(Registers::*setRegister)() const)
// ^^^^^^^^^^^^^^^^^^^^^^^^^ correct syntax
{
std::cout << std::invoke(setRegister, registerList);
}
int main()
{
opcodeLdWordRegister(&Registers::getSP);
return 0;
}
输出:
2
如果您没有 std::invoke
,您仍然可以执行它会执行的操作,即取消引用调用站点中的(唯一)指针。
((*registerList).*setRegister)();