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