I'm getting hung up on some syntax for working with functors and lambdas in C++.
I define functors as:
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();
}
};
I can call these explicitly by doing, e.g.,
paint _paint (characterContext);
get1byte _1byte (fileContext);
_paint(_1byte());
(or this at least compiles).
But then I have
std::array<std::function<void()>, 256> opcodes;
opcodes[64] = [_paint, _1byte](){ _paint(_1byte()); };
which has the compiler complaining,
No matching function for call to object of type 'const get1byte'
How do I get this to work as expected? I'd prefer to avoid modifying the OpCode
operator()
signature to take Argument
since in some instances I'd like to put a lambda in with a constant value in the argument to, e.g., _paint
.
Thanks to Remy Lebeau's directions, I have managed to figure out what I needed to do: I had to add const
to the declarations of my operator functions, e.g.,
int_fast32_t operator()() const override {
return file_context->read1();
}
in an Argument
implementation, with the abstract base class defining the method as
virtual std::int_fast32_t operator()() const = 0;
Then I was able to write my assignments as, e.g.,
opcodes[64] = [=](){ _paint(_1byte()); };
and all was well (or at least doesn't generate compiler errors—we'll see once I've finished updating my code). I've even managed to improve another piece of code using std::generate
to have a lambda make a lambda:
std::generate_n(opcodes.begin(), 64, [&index, _paint](){ auto rv = [=](){_paint(index); }; ++index; return rv; });
and with any luck, all will be well (although since I have a similar construction happening later in the fill, I'll likely refactor the lambda as a function).