C ++;类方法指针;拉姆达;传递lambda作为成员函数指针;

时间:2017-05-11 09:43:53

标签: c++ lambda function-pointers member-function-pointers

这是我尝试实现的目标:

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方法并将lambdas作为回调传递。 捕获this以访问类成员。

获得相同结果的正确方法是什么?
感谢。

PS:此示例的编译返回错误'无法转换:: 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;
});

我也发现了一些可能有用的相关问题 -

Passing lambda as function pointer - “5gon12eder”回答。
C++ lambda with captures as a function pointer

1 个答案:

答案 0 :(得分:2)

你误解了成员函数指针的语义

lodash

是指向void (MyClass::*)(uint8_t idx) 的成员函数的指针,它接受MyClass,它不是别的。你把它称为

uint8_t

其次,MyClass::Callback c = &MyClass::SomeMemberFunction; MyClass mc; (mc.*c)(0); // equivalent to... mc.SomeMemberFunction(0); 的目的是传入的可调用对象不需要知道对象的内部,因此,你不应该在循环中传入索引。

您真正想要的是传入一个可调用对象,该对象接受在每个对象上调用的引用。这可以通过两种方式完成

for_each

两者都可以用lambda

调用
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]);
}

其中MyClass mc; mc.for_each1([](int& i) { i++; }); mc.for_each2([&mc](int& i) { i += mc.increment(); }); 是该实例想要增加的内容。