提问人:Ori Tsachi 提问时间:8/14/2023 最后编辑:Ori Tsachi 更新时间:8/14/2023 访问量:76
将指向成员函数的指针传递给父类
passing a pointer to member function to a parent class
问:
我有一个类,它派生自另一个实现回调函数映射的类 我需要将指向从子项到父项的回调指针传递给父项,但我收到编译转换错误 我试图了解这样做的正确方法是什么......
这是我的课程
class handler
{
public:
handler(){}
using Callback = std::function<void(const string&, const string&)>;
void AddTopicCallbackPair(const string& _st ,Callback _cb)
{
m_callbackDictionary.insert(std::make_pair(_st, _cb));
}
private:
std::map<const string&, Callback> m_callbackDictionary;
};
我通过这个类继承了这个类
class specificHandler : public handler
{
public:
specificHandler()
{
AddTopicCallbackPair("/root/dev/", std::bind(callback1,this));
}
void callback1(const string& _topic, const string& _jsonData);
void callback2(const string& _topic, const string& _jsonData);
private:
}
我想过使用这样的东西
class Handler
{
.....
template <typename T>
using Callback = void(T::*)(const string&, const string&)
.....
}
然后在 specificHandler 中:
Callback f = &specificHandler::callback1;
AddTopicCallbackPair("/root/dev/", std::bind(callback1,this));
但它对我不起作用,我遇到了编译错误:
error: cannot convert 'void (specificHandler::*)(const string&, const string&)' {aka 'void (specificHandler::*)(const std::__cxx11::basic_string<char>&, const std::__cxx11::basic_string<char>&)'} to 'handler::CallbackFunc' {aka 'void (handler::*)(const std::__cxx11::basic_string<char>&, const std::__cxx11::basic_string<char>&)'} in initialization
21 | CallbackFunc f = &specificHandler::callback1;
答:
2赞
JeJo
8/14/2023
#1
由于需要具体类型,因此使用模板类型别名不是一个好主意。事实上,你在这里不需要它。m_callbackDictionary
我会在这里建议 lambda 函数:std::bind
class specificHandler : public handler
{
public:
specificHandler()
{
AddTopicCallbackPair("/root/dev/",
[this](const std::string& _topic, const std::string& _jsonData)
{ return this->callback1(_topic, _jsonData); });
}
// ....code
};
此外,在类中将键类型更改为非常量引用类型。std::map
handler
否则,它将在实例化 的成员函数时出现问题,其中函数重载,将 作为转发引用和 .std::map
key_type
const-&
class handler
{
public:
using Callback = std::function<void(const std::string&, const std::string&)>;
void AddTopicCallbackPair(std::string _st, Callback _cb)
{
m_callbackDictionary.emplace(std::move(_st), _cb);
// construct in-place ^~~~~~~ using std::map::emplace
}
private:
std::map<std::string, Callback> m_callbackDictionary;
// ^~~~~~~~~~~ non-const ref
};
0赞
Jarod42
8/14/2023
#2
std::bind
需要 std::p laceholders::_1
当您需要使用参数调用它时。
所以会是这样
using namespace std::placeholders;
//...
std::bind(&Foo::callback1, this, _1, _2)
您的语法适用于 std::bind_front
(C++20)
std::bind_front(&Foo::callback1, this)
作为替代方案,仍然有 lambda:
[this](const std::string& topic, const std::string& data){ this->Foo::callback1(topic, data); )
评论
Callback
或?请尝试向我们展示一个失败代码的适当最小可重现示例。CallbackFunc
Callback cb = std::bind(&Foo::callback1, this, _1, _2);
srd::bind_front(&callback1, this)