1.. title:: clang-tidy - bugprone-crtp-constructor-accessibility
2
3bugprone-crtp-constructor-accessibility
4=======================================
5
6Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP
7can be constructed outside itself and the derived class.
8
9The CRTP is an idiom, in which a class derives from a template class, where
10itself is the template argument. It should be ensured that if a class is
11intended to be a base class in this idiom, it can only be instantiated if
12the derived class is it's template argument.
13
14Example:
15
16.. code-block:: c++
17
18  template <typename T> class CRTP {
19  private:
20    CRTP() = default;
21    friend T;
22  };
23
24  class Derived : CRTP<Derived> {};
25
26Below can be seen some common mistakes that will allow the breaking of the
27idiom.
28
29If the constructor of a class intended to be used in a CRTP is public, then
30it allows users to construct that class on its own.
31
32Example:
33
34.. code-block:: c++
35
36  template <typename T> class CRTP {
37  public:
38    CRTP() = default;
39  };
40
41  class Good : CRTP<Good> {};
42  Good GoodInstance;
43
44  CRTP<int> BadInstance;
45
46If the constructor is protected, the possibility of an accidental instantiation
47is prevented, however it can fade an error, when a different class is used as
48the template parameter instead of the derived one.
49
50Example:
51
52.. code-block:: c++
53
54  template <typename T> class CRTP {
55  protected:
56    CRTP() = default;
57  };
58
59  class Good : CRTP<Good> {};
60  Good GoodInstance;
61
62  class Bad : CRTP<Good> {};
63  Bad BadInstance;
64
65To ensure that no accidental instantiation happens, the best practice is to
66make the constructor private and declare the derived class as friend. Note
67that as a tradeoff, this also gives the derived class access to every other
68private members of the CRTP.
69
70Example:
71
72.. code-block:: c++
73
74  template <typename T> class CRTP {
75    CRTP() = default;
76    friend T;
77  };
78
79  class Good : CRTP<Good> {};
80  Good GoodInstance;
81
82  class Bad : CRTP<Good> {};
83  Bad CompileTimeError;
84
85  CRTP<int> AlsoCompileTimeError;
86
87Limitations:
88
89* The check is not supported below C++11
90
91* The check does not handle when the derived class is passed as a variadic
92  template argument
93
94* Accessible functions that can construct the CRTP, like factory functions
95  are not checked
96
97The check also suggests a fix-its in some cases.
98
99