禁止使用“static_assert”函数

Forbids functions with `static_assert`

本文关键字:assert 函数 static 禁止      更新时间:2023-10-16

我想阻止某些函数被调用。让我们忽略通过函数指针或其他方式调用函数的情况,只关注直接函数调用的情况。我可以用= delete做到这一点。然而,发布的诊断信息并不丰富。我考虑过使用static_assert,使用它可以提供自定义诊断消息。我在函数体中放置了一个static_assert(false, ...)语句,希望它在调用函数时激发。然而,事实证明,即使没有调用函数,static_assert也会失败。有什么建议吗?

附加说明:无条件禁止此功能。因此,std::enable_if在此不适用。创建这样一个函数的动机是,我想防止某些使用,否则会以过载解决方案编译得很好。所以我不能只是删除函数。deprecated不是我想要的。我想要一个编译错误,而不是警告。

我同意其他人的观点,即根本不应该使用static_assert,而是将该函数标记为不推荐使用。

CCD_ 8离子在编译时激发。对于普通函数,这是解析它的时间,而不是调用它的时间。然而,对于template,它是实例化的时间。所以你可以把你的函数做成这样的template

template <typename...>
struct always_false { static constexpr bool value = false; };
template <typename... Ts>
void
never_call_me(Ts&&...)
{
  static_assert(always_false<Ts...>::value,
                "You should have never called this function!");
}

如果typename...不适合您(因为函数重载),请尝试将其缩小到只匹配您想要出错的内容。

这里使用的技巧是always_false<Ts...>::value取决于类型参数Ts...,因此在template被实例化之前不能对其进行评估。(尽管我们可以清楚地看到它将永远是false。)

如果它是成员函数,那么= delete是最好的(最可移植的)选择。否则,GCC和MSVC都支持将函数标记为"不推荐使用",这将导致编译器在调用函数时发出警告。

从C++标记为弃用:

#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif

用法:

DEPRECATED(void badidea(int a, const char* b));

现在使用C++14,我们可以将其写成:

#define DEPRECATED(func, reason) [[deprecated(reason)]] func

使用:

DEPRECATED( void badidea(int a, const char* b), "This function was a bad idea");

作为@5gon12eder的好答案的较短版本,您可以简单地使用

template<typename ... Ts>
void never_call_me(Ts&&...ts)
{
  static_assert(not (std::is_same_v<Ts,Ts> && ...),
                "You should have never called this function!");
}