bugprone-incorrect-enable-if

检测 std::enable_if 的错误用法,这些用法没有命名嵌套的 type 类型。

在 C++11 中引入了 std::enable_if 作为一种方便的方法来利用 SFINAE。使用 std::enable_if 的一种形式是声明一个未命名的模板类型参数,其默认类型等于 typename std::enable_if<condition>::type。如果作者忘记命名嵌套类型 type,那么即使条件不满足,代码也将始终考虑候选模板。

以下是一些使用 std::enable_if 的代码示例,以及此检查标记的错误示例。

template <typename T, typename = typename std::enable_if<T::some_trait>::type>
void valid_usage() { ... }

template <typename T, typename = std::enable_if_t<T::some_trait>>
void valid_usage_with_trait_helpers() { ... }

// The below code is not a correct application of SFINAE. Even if
// T::some_trait is not true, the function will still be considered in the
// set of function candidates. It can either incorrectly select the function
// when it should not be a candidates, and/or lead to hard compile errors
// if the body of the template does not compile if the condition is not
// satisfied.
template <typename T, typename = std::enable_if<T::some_trait>>
void invalid_usage() { ... }

// The tool suggests the following replacement for 'invalid_usage':
template <typename T, typename = typename std::enable_if<T::some_trait>::type>
void fixed_invalid_usage() { ... }

C++14 引入了特性辅助程序 std::enable_if_t,它降低了出现此错误的可能性。C++20 引入了约束,它通常取代了 std::enable_if 的使用。有关另一个将 std::enable_if 替换为 std::enable_if_t 的工具,请参阅 modernize-type-traits,有关另一个将 std::enable_if 替换为 C++20 约束的工具,请参阅 modernize-use-constraints。尽可能考虑这些更新的机制。