Я ищу способы предотвратить ненужный беспорядок в коде установки в main()
, а также в других местах. У меня часто есть тонны установочного кода, который регистрируется на какой-то фабрике. Стандартный пример, например, обработчики для различных типов файлов.
Чтобы избежать необходимости писать этот код и вместо этого просто заставить обработчики волшебным образом работать, если они связаны с приложением, я подумал, что мог бы заменить код чем-то вроде следующего:
test. cc:
int main() {
return 0;
}
loader.h:
#ifndef LOADER_H_
#define LOADER_H_
#include <functional>
namespace loader {
class Loader {
public:
Loader(std::function<void()> f);
};
} // namespace loader
#define REGISTER_HANDLER(name, f) \
namespace { \
::loader::Loader _macro_internal_ ## name(f); \
}
#endif // LOADER_H_
loader. cc:
#include "loader.h"
#include <iostream>
namespace loader {
Loader::Loader(std::function<void()> f) { f(); }
} // namespace loader
a . cc:
#include <iostream>
#include "loader.h"
REGISTER_HANDLER(a, []() {
std::cout << "hello from a" << std::endl;
})
Идея заключается в том, что a.cc
будет в реальном приложении, например, вызывать некоторый метод, где он сам регистрирует себя в качестве обработчика для определенного типа файла. Компиляция кода с помощью c++ -std=c++11 test.cc loader.cc a.cc
создает двоичный файл, который печатает «привет от», в то время как c++ -std=c++11 test.cc loader.cc
хранит молчание.
Мне интересно, есть ли что-то тонкое, с чем мне, возможно, следует быть осторожным? Например, если кто-то создает сложные объекты в лямбде, который здесь запускается, я предполагаю, что во время очистки могут произойти странные вещи, например, в многопоточном приложении?