xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst (revision ba3447601c435bb2b24ad9e3c8d146c578f00568)
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