确保在编译时只在一个地方调用方法

yoy*_*yoy 14 c++

我很好奇是否有可能在编译时确保在一个地方调用一个方法。

请注意,如果函数被调用多次(例如在一个循环中)是可以的 - 但它不应该在两个单独的循环中调用。

这可以分为两部分,我也对涵盖任一部分的解决方案感兴趣:
(a) 确保至少在一个地方
调用一个方法 (b) 确保一个方法最多在一个地方调用

我可以完全控制代码的结构,欢迎使用实现相同想法的不同习语。

// class.h

class MyClass {
  public:
    void my_method();
}
Run Code Online (Sandbox Code Playgroud)

以下不应编译(从未调用)

#include "class.h"

int main() {
  MyClass my_class;
}
Run Code Online (Sandbox Code Playgroud)

以下不应编译(在多个地方调用)

#include "class.h"

int main() {
  MyClass my_class;
  my_class.my_method();
  while(true) {
    my_class.my_method();
  }
}
Run Code Online (Sandbox Code Playgroud)

以下应该编译(在一个地方调用):

#include "class.h"

int main() {
  MyClass my_class;
  while(true) {
    my_class.my_method();
  }
}
Run Code Online (Sandbox Code Playgroud)

Rum*_*rak 5

低技术方法:

由于您可以控制代码结构(我假设其中包括构建系统),因此这是一个低技术解决方案:

  • 使函数名称足够独特
  • grep 用于代码中的函数名称。您期待它两次(假设您的声明和定义位于同一位置):
    • 一旦在标题中
    • 一旦在单个呼叫站点

或者:

如果你真的,真的,真的想用 C++ 解决它,那么你可以试试

  • 使用编译时间计数器计算编译单元内的使用次数
  • 如果头文件包含在多个编译单元中,请确保该函数会违反 ODR。

然而,编译时间计数器是黑魔法(我说,我真的很喜欢 TMP),为此目的强制 ODR 违规似乎是类似的巫术(至少你需要一个无法链接的测试用例)。

不过实话说:

不要这样做。无论你做什么,它都可以被包装函数毫不费力地扭曲:

auto call_my_method(MyClass& o)
{
   return o.my_method();
}
Run Code Online (Sandbox Code Playgroud)

MyClass::my_method()仅在包装器中调用。其他人只是调用甚至可能由编译器内联的包装器。

正如其他人所建议的那样:如果您能解释一下您要做什么,可能会更有帮助。