modernize-use-constraints¶
Replace std::enable_if with C++20 requires clauses.
std::enable_if is a SFINAE mechanism for selecting the desired function or
class template based on type traits or other requirements. enable_if changes
the meta-arity of the template, and has other
adverse side effects
in the code. C++20 introduces concepts and constraints as a cleaner language
provided solution to achieve the same outcome.
This check finds some common std::enable_if patterns that can be replaced
by C++20 requires clauses. The tool can replace some of these patterns
automatically, otherwise, the tool will emit a diagnostic without a
replacement. The tool can detect the following std::enable_if patterns
std::enable_ifin the return type of a functionstd::enable_ifas the trailing template parameter for function templates
Other uses, for example, in class templates for function parameters, are not
currently supported by this tool. Other variants such as boost::enable_if
are not currently supported by this tool.
Below are some examples of code using 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 {};
The tool will replace the above code with,
// 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 {};
Note
System headers are not analyzed by this check.