brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · 53082f4 Raw
102 lines · plain
1.. title:: clang-tidy - bugprone-crtp-constructor-accessibility2 3bugprone-crtp-constructor-accessibility4=======================================5 6Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP7can be constructed outside itself and the derived class.8 9The CRTP is an idiom, in which a class derives from a template class, where10itself is the template argument. It should be ensured that if a class is11intended to be a base class in this idiom, it can only be instantiated if12the derived class is its 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 the27idiom.28 29If the constructor of a class intended to be used in a CRTP is public, then30it 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 instantiation47is prevented, however it can fade an error, when a different class is used as48the 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 to66make the constructor private and declare the derived class as friend. Note67that as a tradeoff, this also gives the derived class access to every other68private members of the CRTP. However, constructors can still be public or69protected if they are deleted.70 71Example:72 73.. code-block:: c++74 75  template <typename T> class CRTP {76    CRTP() = default;77    friend T;78  };79 80  class Good : CRTP<Good> {};81  Good GoodInstance;82 83  class Bad : CRTP<Good> {};84  Bad CompileTimeError;85 86  CRTP<int> AlsoCompileTimeError;87 88 89Limitations90-----------91 92* The check is not supported below C++1193 94* The check does not handle when the derived class is passed as a variadic95  template argument96 97* Accessible functions that can construct the CRTP, like factory functions98  are not checked99 100The check also suggests a fix-its in some cases.101 102