【问题标题】:C++; class method pointer; lambda; passing lambda as member function pointer;C++;类方法指针;拉姆达;将 lambda 作为成员函数指针传递;
【发布时间】:2017-10-10 05:54:44
【问题描述】:

这是我试图实现的目标:

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:这个例子的编译返回错误'cannot convert ::lambda ....'

回答: 有了“路人”的回答,我完成了代码:

// 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

【问题讨论】:

  • 请让您的问题标题描述问题,而不仅仅是列出内容
  • 此外,这个问题还不清楚。您发布的代码不起作用吗?如果不是,以什么方式?而你想做什么呢? (我们无法从不做那件事的代码中推断出这一点
  • 请包含实际错误消息。它们不是胡言乱语,而是有用的信息,截断它们也无济于事。

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


【解决方案1】:

你弄错了成员函数指针的语义

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 的目的是让传入的可调用对象不需要知道对象的内部结构,因此你不应该在循环中传入索引。

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

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 是该实例想要增加的值。

【讨论】:

  • @Quentin 表明我实际上根本没有使用指向成员函数的指针,我的(非常)糟糕。谢谢。
  • 别担心 :) -
猜你喜欢
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 2012-07-22
  • 2012-10-22
  • 2013-08-11
  • 1970-01-01
相关资源
最近更新 更多