1.. title:: clang-tidy - modernize-use-constraints 2 3modernize-use-constraints 4========================= 5 6Replace ``std::enable_if`` with C++20 requires clauses. 7 8``std::enable_if`` is a SFINAE mechanism for selecting the desired function or 9class template based on type traits or other requirements. ``enable_if`` changes 10the meta-arity of the template, and has other 11`adverse side effects 12<https://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0225r0.html>`_ 13in the code. C++20 introduces concepts and constraints as a cleaner language 14provided solution to achieve the same outcome. 15 16This check finds some common ``std::enable_if`` patterns that can be replaced 17by C++20 requires clauses. The tool can replace some of these patterns 18automatically, otherwise, the tool will emit a diagnostic without a 19replacement. The tool can detect the following ``std::enable_if`` patterns 20 211. ``std::enable_if`` in the return type of a function 222. ``std::enable_if`` as the trailing template parameter for function templates 23 24Other uses, for example, in class templates for function parameters, are not 25currently supported by this tool. Other variants such as ``boost::enable_if`` 26are not currently supported by this tool. 27 28Below are some examples of code using ``std::enable_if``. 29 30.. code-block:: c++ 31 32 // enable_if in function return type 33 template <typename T> 34 std::enable_if_t<T::some_trait, int> only_if_t_has_the_trait() { ... } 35 36 // enable_if in the trailing template parameter 37 template <typename T, std::enable_if_t<T::some_trait, int> = 0> 38 void another_version() { ... } 39 40 template <typename T> 41 typename std::enable_if<T::some_value, Obj>::type existing_constraint() requires (T::another_value) { 42 return Obj{}; 43 } 44 45 template <typename T, std::enable_if_t<T::some_trait, int> = 0> 46 struct my_class {}; 47 48The tool will replace the above code with, 49 50.. code-block:: c++ 51 52 // warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints] 53 template <typename T> 54 int only_if_t_has_the_trait() requires T::some_trait { ... } 55 56 // warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints] 57 template <typename T> 58 void another_version() requires T::some_trait { ... } 59 60 // The tool will emit a diagnostic for the following, but will 61 // not attempt to replace the code. 62 // warning: use C++20 requires constraints instead of enable_if [modernize-use-constraints] 63 template <typename T> 64 typename std::enable_if<T::some_value, Obj>::type existing_constraint() requires (T::another_value) { 65 return Obj{}; 66 } 67 68 // The tool will not emit a diagnostic or attempt to replace the code. 69 template <typename T, std::enable_if_t<T::some_trait, int> = 0> 70 struct my_class {}; 71 72.. note:: 73 74 System headers are not analyzed by this check. 75