首页 > 解决方案 > 在 lambda 中使用仿函数

问题描述

我对在 C++ 中使用仿函数和 lambdas 的一些语法感到困惑。

我将函子定义为:

class paint : public OpCode {
public:
    using OpCode::OpCode;

    void operator()(std::int_fast32_t d) override {
        if (character_context->is_black()) {
            character_context->bitmap.add_blackline(character_context->m, character_context->n, d);
        }
        character_context->m += d;
        character_context->toggle_color();
    }

};

class get1byte : public Argument {
public:
    using Argument::Argument;

    int_fast32_t operator()() override {
        return file_context->read1();
    }
};

我可以通过这样做明确地调用这些,例如,

paint _paint (characterContext);
get1byte _1byte (fileContext);

_paint(_1byte());

(或者这至少编译)。

但后来我有

std::array<std::function<void()>, 256> opcodes;
opcodes[64] = [_paint, _1byte](){ _paint(_1byte()); };

编译器抱怨,

No matching function for call to object of type 'const get1byte'

我如何让它按预期工作?我宁愿避免修改OpCode operator()要采用的签名,Argument因为在某些情况下,我想在参数中放入一个带有常量值的 lambda,例如_paint.

标签: c++lambdafunctor

解决方案


感谢 Remy Lebeau 的指导,我已经设法弄清楚我需要做什么:我必须添加const到我的操作员函数的声明中,例如,

int_fast32_t operator()() const override {
    return file_context->read1();
}

Argument实现中,抽象基类将方法定义为

virtual std::int_fast32_t operator()() const = 0;

然后我可以将我的作业写成,例如,

opcodes[64] = [=](){ _paint(_1byte()); };

一切都很好(或者至少不会产生编译器错误——我们会在我完成代码更新后看到)。我什至设法改进了另一段使用std::generatelambda 制作 lambda 的代码:

std::generate_n(opcodes.begin(), 64, [&index, _paint](){ auto rv = [=](){_paint(index);  }; ++index; return rv; });

运气好的话,一切都会好起来的(尽管由于我在填充的后面发生了类似的构造,我可能会将 lambda 重构为一个函数)。


推荐阅读