我正在编写一个类来包装与设备一起使用的基于 C 的库的一部分,其中每个设备都配置有用于处理数据的回调函数指针。MyClass将为每个设备创建一个实例。见下文:
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).
}
};
Run Code Online (Sandbox Code Playgroud)
由于捕获 lambda 无法转换为函数指针,因此我尝试了以下解决方法:
template<MyClass *MC>
auto binder() {
return [](char *data) { MC->myCallback(data); };
}
MyClass::MyClass() {
config.callback = binder<this>();
}
Run Code Online (Sandbox Code Playgroud)
然而,编译器(最新的 GCC)不喜欢binder在构造函数中使用,因为this在编译时不一定知道,尽管我知道 的实例MyClass只会在编译时声明。
C++20 引入了“必须生成编译时常量”consteval的函数(和构造函数) 。。但是,添加到构造函数和/或不会影响编译器的输出。也不会改变事情。constevalbinderconstexpr
如果一个对象可以在编译时初始化,为什么不能this在编译时知道该对象呢?是否可以通过其他方式实现上述目标?
构造函数是函数,就像其他函数一样。与其他函数相比,它们几乎没有什么特殊特权,并且它们的参数的常量表达式行为也不是其中之一。
this本质上是所有非静态成员函数的参数。参数从来都不是常量表达式。因此,this不能在需要常量表达式的上下文中使用。如何创建类实例并不重要。你怎么称呼它并不重要。函数的参数constexpr/consteval从来都不是常量表达式,其中包括this.