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