I'm writing a class to wrap around part of a C-based library that works with devices, where each device is configured with a callback function poiner for handling data. An instance of MyClass
would be made for each device. See below:
struct DeviceConfig {
void (*callback)(char *data);
};
class MyClass {
private:
DeviceConfig config;
public:
void myCallback(char *data);
MyClass() {
// Would like to set config.callback so that a call to it will result in a call of this->myCallback(data).
}
};
Since a capturing lambda can't be converted to a function pointer, I've tried the following as a workaround:
template<MyClass *MC>
auto binder() {
return [](char *data) { MC->myCallback(data); };
}
MyClass::MyClass() {
config.callback = binder<this>();
}
However, the compiler (GCC latest) doesn't like binder
being used in the constructor, as this
isn't necessarily known at compile-time, though I know that instances of MyClass
will only be declared at compile-time.
C++20 introduced consteval
functions (and constructors) which "must produce a compile-time constant.". However, adding consteval
to the constructor and/or binder
doesn't affect the compiler's output. constexpr
doesn't change things either.
If an object can be initialized at compile-time, why can't the object's this
be known at compile-time too? Can the above be achieved through some other manner?