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_if
in the return type of a functionstd::enable_if
as 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 {};