是否可以在编译时初始化对象的 C 样式函数指针,以便它调用对象的成员函数?
Can I initialize an object's C style function pointer at compile time so that it calls the object's member function?
我正在编写一个类来包装一个需要回调函数指针的库。见下文:
struct LibraryConfig {
// Omitting other members...
void (*callback)(const char *);
};
class MyClass {
private:
LibraryConfig m_config;
public:
MyClass(const LibraryConfig &config) {
// Initialize m_config using config, would like to set callback so that it calls
// this->myCallback().
}
void myCallback(const char *);
};
只会声明 MyClass 的静态实例,因此构造可以保留在编译时间内。我已经尝试了采用 MyClass 指针的 lambda 和模板函数,但我要么无法在构造函数中完成此操作,要么无法在编译时实现(在编译时通过this
或&myClass
获取实例的地址似乎是不可能的(。
将来可能会允许constexpr
参数,这使得实现起来变得微不足道,但是现在有没有办法用 C++20 来实现这一点?
是的,这显然是可能的。请参阅以下片段:
struct LibraryConfig {
void (*callback)(const char *);
};
class MyClass {
private:
LibraryConfig config;
public:
consteval MyClass(const LibraryConfig& cfg) :
config(cfg) {}
void myCallback(const char *data);
};
int main()
{
constinit static MyClass mc = {{
[](const char *data) { mc.myCallback(data); }
}};
}
在此处查看编译器资源管理器的工作示例。由于mc
是静态的,因此允许 lambda 访问它而无需捕获。此解决方案可能有改进的余地,例如,由函数生成 lambda。
编辑:
我想出了一个通用函数来创建lambda:
template<auto& inst, auto func>
consteval auto make_member_callback()
{
return []<typename... Args>(Args... args) { (inst.*func)(args...); };
}
这允许执行以下操作(编译器资源管理器(:
constinit static MyClass mc {{
make_member_callback<mc, &MyClass::myCallback>()
}};
编辑 2:
这是我的最后一次尝试,初始化是在类中完成的:
struct LibraryConfig {
void (*callback)(const char *);
};
template<auto& v, auto f>
constexpr auto member_callback = [](auto... args) { (v.*f)(args...); };
class MyClass {
private:
LibraryConfig config;
public:
consteval MyClass(const LibraryConfig& cfg = {}) :
config(cfg) {}
template<MyClass& MC>
constexpr static MyClass& init() {
MC.config.callback = member_callback<MC, &MyClass::myCallback>;
return MC;
}
void myCallback(const char *data);
};
int main()
{
constinit static MyClass mc = (mc = MyClass(), MyClass::init<mc>());
}
相关文章:
- 如何使用单独文件中的派生类访问友元函数对象
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 有没有办法将重载的类函数绑定到函数对象?
- 将指针传递到成员的指针,从模板参数包到函数对象
- 如何在类模板的成员函数中正确调用函数对象?正在生成 Visual Studio 编译器错误 C2440
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- C++使用函数对象的线程,如何调用多个析构函数而不是构造函数?
- 如何通过接口将函子分配给函数对象
- 对std::函数对象的调用不匹配,该对象是指向成员函数的指针
- 指向std::invoke中成员函数对象的指针
- 如何成功地将函数对象(或lambda)传递给trackbar回调的第二个参数(void*)
- "std::function"的简单版本:函数对象的生存期?
- C++ 将函数对象作为左值和/或右值传递
- SFINAE 用于具有默认参数的函数对象
- 构造函数对象赋值是否泄漏内存
- 如何发送通过绑定到函数/方法创建的函数对象?
- std::for_each 与函数对象
- 将函数对象传递给 std::function
- 访问执行策略for_each函数对象中的迭代器
- 通过C++函数对象类访问参数