正在排队 headers 中的呼叫
Queuing a call in headers
目标是允许 header 个文件到 "register" 一个初始化函数,这样 main 就可以迭代这些函数并调用它们。我偶然发现了一个使用 __attribute__
的解决方案,但它似乎是 GCC-only ().
// header1.h
void myInitializer(){}
REGISTER_THIS(&myInitializer);
// header2.h
void myInitializer2(){}
REGISTER_THIS(&myInitializer2);
// main.cpp
...
for_each_registered_ptr(){ call_ptr(); } // calls myInitializer and myInitializer2
...
是否有通用的解决方案?如果更容易实现,可以使用 类 或类型切换功能。
您可以滥用 static
局部函数来做到这一点,避免静态初始化顺序失败。
在 init.h
中,我们有这个:
#ifndef INIT_H
#define INIT_H
#include <vector>
// Can be changed to std::function<...> or whatever you need.
typedef void (*init_fn)();
// Returns int so it can easily be used in a variable initializer.
int register_initializer(init_fn fn);
std::vector<init_fn> & get_initializers();
#endif
然后,在init.cpp
:
#include "init.h"
int register_initializer(init_fn fn)
{
get_initializers().push_back(fn);
return 0;
}
std::vector<init_fn> & get_initializers()
{
static std::vector<init_fn> ip;
return ip;
}
一些注意事项,在我们继续其余部分之前:
static
局部只初始化一次,第一次调用函数。
- "global" 向量有点泄露。除非您向该向量中添加数万个条目,否则这不太可能成为问题。使用后可以随时
get_initializers().clear()
清空。
我们会像这样使用它,在 a.cpp
:
#include <iostream>
#include "init.h"
static void a_init() { std::cout << "a_init()\n"; }
static auto dummy = register_initializer(a_init);
最后,我们(相当简单)main.cpp
:
#include "init.h"
int main() {
for (auto fn : get_initializers()) {
fn();
}
return 0;
}
目标是允许 header 个文件到 "register" 一个初始化函数,这样 main 就可以迭代这些函数并调用它们。我偶然发现了一个使用 __attribute__
的解决方案,但它似乎是 GCC-only ().
// header1.h
void myInitializer(){}
REGISTER_THIS(&myInitializer);
// header2.h
void myInitializer2(){}
REGISTER_THIS(&myInitializer2);
// main.cpp
...
for_each_registered_ptr(){ call_ptr(); } // calls myInitializer and myInitializer2
...
是否有通用的解决方案?如果更容易实现,可以使用 类 或类型切换功能。
您可以滥用 static
局部函数来做到这一点,避免静态初始化顺序失败。
在 init.h
中,我们有这个:
#ifndef INIT_H
#define INIT_H
#include <vector>
// Can be changed to std::function<...> or whatever you need.
typedef void (*init_fn)();
// Returns int so it can easily be used in a variable initializer.
int register_initializer(init_fn fn);
std::vector<init_fn> & get_initializers();
#endif
然后,在init.cpp
:
#include "init.h"
int register_initializer(init_fn fn)
{
get_initializers().push_back(fn);
return 0;
}
std::vector<init_fn> & get_initializers()
{
static std::vector<init_fn> ip;
return ip;
}
一些注意事项,在我们继续其余部分之前:
static
局部只初始化一次,第一次调用函数。- "global" 向量有点泄露。除非您向该向量中添加数万个条目,否则这不太可能成为问题。使用后可以随时
get_initializers().clear()
清空。
我们会像这样使用它,在 a.cpp
:
#include <iostream>
#include "init.h"
static void a_init() { std::cout << "a_init()\n"; }
static auto dummy = register_initializer(a_init);
最后,我们(相当简单)main.cpp
:
#include "init.h"
int main() {
for (auto fn : get_initializers()) {
fn();
}
return 0;
}