在C++中实现对include的能力发现的地道做法

编程语言 2026-07-11

两次我都遇到这样的需求:在一个被包含的C++文件中向全局能力列表添加某些能力,我在想实现的最佳方式是什么。

我有两个用例:

测试发现

我想在多个文件中定义一组测试,然后在 test.cpp 中执行如下操作:

#include "module1/test.h"
#include "module2/test.h"

#include "test.h"

int main() {
  for (const auto& test : autodiscover()) {
  // or `for (const auto& test : TESTS)`
    test();
  }
}

(包括错误报告以及其他信息。)

数据库仓库预处理语句设置

我有一个项目,由一堆不同的可执行文件组成,可以想象成微服务(尽管并非完全如此),它们在某种程度上都在同一个数据库上工作。出于下面不展开说明的原因,每条对数据库执行的语句都在可执行启动时被 PREPAREd提前处理。 This sentence is kept as: "出于下面不展开说明的原因,每条对数据库执行的语句都在可执行启动时被 PREPAREd提前处理。" 这是通过一个 repo::init() 函数来完成的。

就目前而言,该函数有一个静态定义的 prepareSomething()s数组,并按顺序调用它们。

这很不幸,因为这意味着我不能把仓库拆分成多个翻译单元,而我也希望能这样做。

比如说,我希望更新 updateCustomerEmail() 不会引发对 monthly-earnings-report 可执行文件的重新编译,尽管后者根本没有调用前者。

为此,我希望仓库的每个片段都把它的 prepareXYZ()s添加到一个全局的“要初始化的项”列表中,这样当主可执行文件调用 repo::init() 时,能执行的语句都已经准备好,其他的都不会再被准备。

我觉得我想做的事情是可能的,甚至可能很容易实现,因为一切都能在编译时获得,但我找不到实现的方法。我的所有谷歌搜索都只把我引导到服务发现,并让我去使用网络层,显然这并不是我要解决的问题。

解决方案

关于自注册,请参考Google Test的做法:从

TEST(Fix, Tst)
{ my code }

它会生成类似这样的代码

class Fix_Tst_Test{
    void TestBody() override;
    static ::testing::TestInfo *const test_info_ __attribute__((unused));
};
::testing::TestInfo *const Fix_Tst_Test::test_info_
    = ::testing::internal::MakeAndRegisterTestInfo(
        "Fix",
        "Tst",
        // other parameters
    );
void Fix_Tst_Test::TestBody()
{ my code }

注册是由用于初始化静态成员的函数来完成的,该函数在调用 main() 之前执行。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章