Прежде всего, указанный вами код и сообщение об ошибке не совпадают. Для данного кода вы должны получить (из 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 ):
((*registerList).*setRegister)();
Теперь должно появиться сообщение об ошибке, которое было показано в вопросе: no match for ‘operator->*
должно появиться, когда вы попробуете следующий синтаксис. ( Минимальный воспроизводимый код )
(registerList->*setRegister)();
Это связано с тем, что интеллектуальные указатели не имеют оператора доступа указатель на элемент , определенного в стандарте. Поэтому вам нужно перейти к разыменованию интеллектуального указателя с помощью operator*
или с помощью функции-члена std::unique_ptr::get
и вызвать функцию-член.
Использование члена std::unique_ptr::get
с правильным синтаксисомбудет ( См. живую демоверсию онлайн )
(registerList.get()->*setRegister)()
При этом, если у вас есть доступ к c ++ 17 используйте унифицированную версию функции invoker 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