我将函数指针作为参数传递时遇到了问题。
指向函数类型的指针的声明:
typedef void(*cbk_fct)(void);
类Operation
的构造函数接受cbk_fct
作为参数,声明如下:
class Operation
{
private:
cbk_fct m_fct_ptr;
public:
Operation(cbk_fct fct_ptr);
};
Operation::Operation(cbk_fct fct_ptr):
m_fct_ptr(fct_ptr)
{
}
现在类User
将调用Operation
的构造方法
class User
{
public:
User();
void userOperation();
};
void User::userOperation()
{
cout << "User operation"<<endl;
}
User::User()
{
Operation op(userOperation); // This version doesnt work
}
此呼叫将产生以下错误:
no matching function for call to 'Operation::Operation(<unresolved overloaded function type>)'|
no known conversion for argument 1 from '<unresolved overloaded function type>' to 'cbk_fct {aka void (*)()}'
但是,如果我声明将函数作为参数传递给类之外,它将被接受
void UserOperationNotInClass()
{
cout << "User operation"<<endl;
}
User::User()
{
Operation op(UserOperationNotInClass); // This version works
}
很明显,错误消息提到它不能从''转换为'cbk_fct,但是这种类型的'未解析的重载函数类型'是从哪里来的
答案 0 :(得分:1)
非静态成员函数与普通函数不是同一件事。具体来说,它可以访问其对象this
指针,这对于 normal 函数而言毫无意义。因此,编译器在说不存在从前者到后者的未知转换时是正确的。
答案 1 :(得分:0)
与自由函数不同,没有从成员函数到指向成员函数的指针的隐式转换,因此您永远无法提供userOperation
。您必须使用&User::userOperation
。在这方面,错误消息可能会更好。
已修复以下问题:&User::userOperation
具有类型void (User::*)(void)
,与类型void (*)(void)
(别名cbk_fct
)不同。您总是需要一个User
才能调用userOperation
,而这无处可去。如果要使其包含成员函数,则必须更改Operation
。
(C兼容)C ++ 98的方式是在函数类型和void *
的成员中都包含一个Operation
,并传递this
(或任何其他对象指针),隐式转换为void *
。
typedef void * context_ptr;
typedef void (* action_ptr)(context_ptr);
class Operation
{
private:
action_ptr m_action;
context_ptr m_context;
public:
Operation(action_ptr action, context_ptr context);
};
Operation::Operation(action_ptr action, context_ptr context):
m_action(action), m_context(context)
{}
class User
{
static void callUserOperation(context_ptr);
public:
User();
void userOperation();
};
void User::callUserOperation(context_ptr context)
{
User * user = reinterpret_cast<User *>(context);
user->userOperation();
}
void User::userOperation()
{
cout << "User operation"<<endl;
}
User::User()
{
Operation op(&User::callUserOperation, this);
}
在C ++ 11中,您可以使用std::function
来保存具有特定签名的任何函数对象,并从捕获this
并调用userOperation
的lambda中构造它。
using action_ptr = std::function<void(void)>;
class Operation
{
private:
action_ptr m_action;
public:
Operation(action_ptr action);
};
Operation::Operation(action_ptr action):
m_action(action)
{}
class User
{
public:
User();
void userOperation();
};
void User::userOperation()
{
cout << "User operation"<<endl;
}
User::User()
{
Operation op([this]{ userOperation(); });
}