4

我想阻止调用某些函数。让我们忽略通过函数指针或其他东西调用函数的情况,只关注直接函数调用的情况。我可以用= delete. 但是,发出的诊断信息并不十分丰富。我考虑使用static_assert,您可以使用它提供自定义诊断消息。我static_assert(false, ...)在函数体内放置了一条语句,希望它在函数被调用时触发。但是,事实证明static_assert即使没有调用该函数也会失败。有什么建议么?

附加说明:该功能是无条件禁止的。所以,std::enable_if这里不适用。这样一个函数的动机是我想阻止某些使用,否则它可以通过重载解析很好地编译。所以我不能只删除该功能。deprecated不是我想要的。我想要一个编译错误,而不是一个警告。

4

2 回答 2

7

我同意其他人的观点,即您根本不应该使用static_assert此功能,而是将该功能标记为已弃用。

static_assert离子在它们被编译时激发。对于一个普通函数来说,这是解析它的时间,而不是调用它的时间。然而,对于 atemplate来说,它是实例化的时间。所以你可以让你的函数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。)

于 2016-01-12T14:17:59.920 回答
4

如果它是成员函数,那么= 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");
于 2016-01-12T14:04:21.617 回答