c++ - 如何使用智能指针对象执行成员函数指针?
问题描述
我正在尝试member-function
使用智能指针实例执行一个类。这个函数的地址是按值传递的,我想通过相应类的智能指针实例来调用它。
我已经尝试过了:
(registerList.*setRegister)();
但它出错了:
no match for ‘operator->*
Register
类成员函数:
uint16_t Registers::getSP()
{
return this->sp;
}
代码片段:
std::unique_ptr<Registers> registerList;
SetRegisteropcodeLdWordRegister(&Registers::getSP)
void opcodeLdWordRegister(uint16_t (*Registers::setRegister)())
{
(registerList.*setRegister)();
}
解决方案
首先,您显示的代码和错误消息不匹配。对于给定的代码,您应该(从 clang)收到以下错误消息
error: left hand operand to .* must be a class compatible with the right hand operand, but is 'std::unique_ptr<Registers>'
(registerList.*setRegister)();
^
这可以通过取消引用指针来解决(就像在@Caleth's answer中一样):
((*registerList).*setRegister)();
现在问题中显示的错误消息:no match for ‘operator->*
应该在您尝试以下语法时出现。(最小可重现代码)
(registerList->*setRegister)();
这是因为智能指针没有标准中定义的指向成员的访问运算符。因此,您需要operator*
通过成员函数或通过成员函数取消引用智能指针std::unique_ptr::get
,并调用成员函数。
使用该成员std::unique_ptr::get
的正确语法是(请参阅在线现场演示)
(registerList.get()->*setRegister)()
话虽如此,如果您有权访问c++17 ,请使用统一版本的函数调用std::invoke
程序来调用具有相应实例的成员函数,通过它您可以忘记(可能)复杂的operator->*
.
您的代码也有几个问题:
您的成员函数指针类型错误。
opcodeLdWordRegister
应该是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。
以下是该案例的最小完整示例:(参见在线现场演示)
#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
推荐阅读
- php - 如何计算 JSON 对象中存在的元素数量?
- git - Git Stat:没有这样的文件或目录
- odata - 无法将更新的 oData 绑定到 sapui5 视图
- javascript - 如何在设置状态元素之前停止将其传递给子组件?
- java - 如何创建自定义 Jackson 注释以在序列化时附加属性
- asp.net-core - 使用 $select 或 $filter 时 OData 默认为帕斯卡大小写
- python - 来自端点的 AWS 负载均衡器
- installation - Joomla 缺少组件
- javascript - 在本地主机上找不到图像,角度出现 404 错误
- javascript - 尽管正确发送令牌,Django服务器仍报告“禁止(CSRF令牌丢失或不正确。)”?