modernize-use-constraints

std::enable_if 替换为 C++20 的 requires 子句。

std::enable_if 是一种 SFINAE 机制,用于根据类型特征或其他要求选择所需函数或类模板。 enable_if 改变了模板的元组元数,并在代码中产生其他负面影响。C++20 引入了概念和约束,作为一种更清晰的语言提供的解决方案来实现相同的目的。

此检查会找到一些常见的 std::enable_if 模式,这些模式可以用 C++20 的 requires 子句替换。该工具可以自动替换其中的一些模式,否则会发出诊断信息,但不会进行替换。该工具可以检测以下 std::enable_if 模式

  1. 函数返回类型中的 std::enable_if

  2. 函数模板的尾随模板参数中的 std::enable_if

目前该工具不支持其他用途,例如类模板中函数参数的用途。目前,该工具也不支持其他变体,例如 boost::enable_if

以下是一些使用 std::enable_if 的代码示例。

// enable_if in function return type
template <typename T>
std::enable_if_t<T::some_trait, int> only_if_t_has_the_trait() { ... }

// enable_if in the trailing template parameter
template <typename T, std::enable_if_t<T::some_trait, int> = 0>
void another_version() { ... }

template <typename T>
typename std::enable_if<T::some_value, Obj>::type existing_constraint() requires (T::another_value) {
  return Obj{};
}

template <typename T, std::enable_if_t<T::some_trait, int> = 0>
struct my_class {};

该工具将用以下代码替换上述代码:

// warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
template <typename T>
int only_if_t_has_the_trait() requires T::some_trait { ... }

// warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
template <typename T>
void another_version() requires T::some_trait { ... }

// The tool will emit a diagnostic for the following, but will
// not attempt to replace the code.
// warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints]
template <typename T>
typename std::enable_if<T::some_value, Obj>::type existing_constraint() requires (T::another_value) {
  return Obj{};
}

// The tool will not emit a diagnostic or attempt to replace the code.
template <typename T, std::enable_if_t<T::some_trait, int> = 0>
struct my_class {};

注意

此检查不会分析系统头文件。