c++ - 如何在编译时检查函数是否被调用

标签 c++

我试图在编译时确定一个函数是否被调用过。具体来说,如果是,我想抛出一个静态断言失败:

template <typename T>
auto Function(T value) -> std::enable_if<someCondition, int>
{
  // this is the function I want to call
}

template <typename... T>
int Function(T...)
{
  // This function should never be called, instead I want
  // a compile-time failure if this is called, because it
  // means the above function wasn't successfully resolved.
}

我想这样做的原因是因为未能在正确的条件下正确调用 Function() 会导致数千行编译器错误消息,这些消息对任何正在使用的人都没有多大帮助对代码库不太熟悉。

我不想在 Function 中放置 static_assert 的原因是因为我们有很多这样的函数,而且我们有办法生成 Catch-all 版本通过宏,这将避免代码库不必要的增长,同时产生更多有用的错误消息。

这个可以吗?

最佳答案

根据您对问题的评论,您不需要 static_assert这里:

template <typename T>
auto Function(T value) -> std::enable_if<someCondition, int>
{
  // this is the function I want to call
}

...但是 static_assert 实际上并没有什么问题这里:

template <typename... T>
struct dependent_false { static constexpr bool value = false; };

template <typename... T>
int Function(T...)
{
  static_assert(dependent_false<T...>::value, "you are passing the wrong arguments!");
}

正如您正确指出的,一个简单的 static_assert(false, "...");在模板定义时会失败。要获得仅在实例化时失败的东西,您需要一个依赖表达式和 dependent_false helper struct 是一种获取依赖于类型的东西的简单方法,几乎​​总是 false , 但不能被编译器假定为真正总是 false : 编译器不能排除你添加部分特化来制作 dependent_false<...>::value true对于某种类型。


回过头来看这个老问题,可能有一个更简单的答案:将重载标记为已删除。

template <typename T>
auto Function(T value) -> std::enable_if<someCondition, int>
{
    // this is the function I want to call
}

template <typename... T>
int Function(T...) = delete;

这并不完全相同,因为这允许调用者检查例如Function(int, int)而不是强制错误,但它更具可读性,并且通常您希望除非函数被实际使用,而不是仅仅被引用,否则不会出现错误的确切行为。

关于c++ - 如何在编译时检查函数是否被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25654632/

相关文章:

c++ - 我应该如何正确地从函数返回一个 vector 以避免额外的复制?

c++ - 二进制比特流与三元比特流的转换?

c++ - dlopen 找不到分解的符号

c++ - 无效的堆参数 : allocated with operator new[], 通过运算符(operator)删除释放

Mac OSX 10.6 上的 C++ 开发

C++ 二维数组 : Each element is given a number but output is a different number

c++ - 将 "ascii art"printf 放入 char 数组?

c++ - 如何在 Windows 中获取当前操作系统版本的描述?

c++ - 模板函数奇怪的链接器错误

c++ - 使用 Boost,如何将自定义边缘属性作为结构放置/获取?