tidy - modernize-use-constraints — Extra Clang Tools 22.0.0git documentation (original) (raw)

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_ifchanges the meta-arity of the template, and has otheradverse side effectsin 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

  1. std::enable_if in the return type of a function
  2. std::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_ifare not currently supported by this tool.

Below are some examples of code using std::enable_if.

// enable_if in function return type template 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 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 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 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 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.