C++; class 方法指针;拉姆达;将 lambda 作为成员函数指针传递;
C++; class method pointer; lambda; passing lambda as member function pointer;
这是我努力实现的目标:
class MyClass
{
public:
using Callback = void(MyClass::*)(uint8_t idx);
void forEach(Callback callback);
private:
int m_buf[64];
int m_x;
int m_y;
MyObject m_object;
}
void MyClass::forEach(Callback callback)
{
size_t s = m_object.size();
for(size_t i = 0; i < s; i++)
callback(i);
}
void MyClass::f1()
{
forEach([this](uint8_t idx)
{
m_buf[idx]++;
});
}
void MyClass::f2()
{
forEach([this](uint8_t idx)
{
m_buf[idx] = m_x + m_y * idx;
});
}
所以有很多方法可以修改m_buf[]
。为了避免复制和粘贴 'get size + for loop',我想添加一个 forEach
方法并将 lambda 作为回调传递。
this
被捕获以访问 class 成员。
达到相同结果的正确方法是什么?
谢谢。
PS: 本例编译returns错误'cannot convert ::lambda ....'
答案:
有了 "Passer By" 答案,我完成了代码:
// Class declaration in header
using Callback = std::function<void(uint8_t)>;
void forEach(Callback callback);
// forEach() is as above
// forEach() call looks like
forEach([this](uint8_t idx) {
m_buf[idx] = m_x + m_y * idx;
});
我还找到了一些可能有用的相关问答
- “5gon12eder”答案。
C++ lambda with captures as a function pointer
你弄错了成员函数指针的语义
void (MyClass::*)(uint8_t idx)
是一个指向接受uint8_t
的MyClass
成员函数的指针,它不是别的。你称它为
MyClass::Callback c = &MyClass::SomeMemberFunction;
MyClass mc;
(mc.*c)(0); // equivalent to...
mc.SomeMemberFunction(0);
其次,for_each
的目的是让传入的可调用对象不需要知道对象的内部结构,因此,你不应该在循环中传入索引。
您真正想要的是传入一个可调用对象,该对象接受对每个对象调用的引用。这可以通过两种方式完成
template<typename Callable>
void for_each1(Callable&& call)
{
for(size_t i = 0; i < size(); i++)
call(m_buf[i]);
}
#include<functional>
void for_each2(std::function<void (int&)>&& fn)
{
for(size_t i = 0; i < size(); i++)
fn(m_buf[i]);
}
两者都可以用 lambda 调用
MyClass mc;
mc.for_each1([](int& i) { i++; });
mc.for_each2([&mc](int& i) { i += mc.increment(); });
其中 mc.increment
是该实例要增加的值。
这是我努力实现的目标:
class MyClass
{
public:
using Callback = void(MyClass::*)(uint8_t idx);
void forEach(Callback callback);
private:
int m_buf[64];
int m_x;
int m_y;
MyObject m_object;
}
void MyClass::forEach(Callback callback)
{
size_t s = m_object.size();
for(size_t i = 0; i < s; i++)
callback(i);
}
void MyClass::f1()
{
forEach([this](uint8_t idx)
{
m_buf[idx]++;
});
}
void MyClass::f2()
{
forEach([this](uint8_t idx)
{
m_buf[idx] = m_x + m_y * idx;
});
}
所以有很多方法可以修改m_buf[]
。为了避免复制和粘贴 'get size + for loop',我想添加一个 forEach
方法并将 lambda 作为回调传递。
this
被捕获以访问 class 成员。
达到相同结果的正确方法是什么?
谢谢。
PS: 本例编译returns错误'cannot convert ::lambda ....'
答案: 有了 "Passer By" 答案,我完成了代码:
// Class declaration in header
using Callback = std::function<void(uint8_t)>;
void forEach(Callback callback);
// forEach() is as above
// forEach() call looks like
forEach([this](uint8_t idx) {
m_buf[idx] = m_x + m_y * idx;
});
我还找到了一些可能有用的相关问答
C++ lambda with captures as a function pointer
你弄错了成员函数指针的语义
void (MyClass::*)(uint8_t idx)
是一个指向接受uint8_t
的MyClass
成员函数的指针,它不是别的。你称它为
MyClass::Callback c = &MyClass::SomeMemberFunction;
MyClass mc;
(mc.*c)(0); // equivalent to...
mc.SomeMemberFunction(0);
其次,for_each
的目的是让传入的可调用对象不需要知道对象的内部结构,因此,你不应该在循环中传入索引。
您真正想要的是传入一个可调用对象,该对象接受对每个对象调用的引用。这可以通过两种方式完成
template<typename Callable>
void for_each1(Callable&& call)
{
for(size_t i = 0; i < size(); i++)
call(m_buf[i]);
}
#include<functional>
void for_each2(std::function<void (int&)>&& fn)
{
for(size_t i = 0; i < size(); i++)
fn(m_buf[i]);
}
两者都可以用 lambda 调用
MyClass mc;
mc.for_each1([](int& i) { i++; });
mc.for_each2([&mc](int& i) { i += mc.increment(); });
其中 mc.increment
是该实例要增加的值。