CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
102 lines
2.4 KiB
ReStructuredText
102 lines
2.4 KiB
ReStructuredText
.. title:: clang-tidy - bugprone-crtp-constructor-accessibility
|
|
|
|
bugprone-crtp-constructor-accessibility
|
|
=======================================
|
|
|
|
Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP
|
|
can be constructed outside itself and the derived class.
|
|
|
|
The CRTP is an idiom, in which a class derives from a template class, where
|
|
itself is the template argument. It should be ensured that if a class is
|
|
intended to be a base class in this idiom, it can only be instantiated if
|
|
the derived class is its template argument.
|
|
|
|
Example:
|
|
|
|
.. code-block:: c++
|
|
|
|
template <typename T> class CRTP {
|
|
private:
|
|
CRTP() = default;
|
|
friend T;
|
|
};
|
|
|
|
class Derived : CRTP<Derived> {};
|
|
|
|
Below can be seen some common mistakes that will allow the breaking of the
|
|
idiom.
|
|
|
|
If the constructor of a class intended to be used in a CRTP is public, then
|
|
it allows users to construct that class on its own.
|
|
|
|
Example:
|
|
|
|
.. code-block:: c++
|
|
|
|
template <typename T> class CRTP {
|
|
public:
|
|
CRTP() = default;
|
|
};
|
|
|
|
class Good : CRTP<Good> {};
|
|
Good GoodInstance;
|
|
|
|
CRTP<int> BadInstance;
|
|
|
|
If the constructor is protected, the possibility of an accidental instantiation
|
|
is prevented, however it can fade an error, when a different class is used as
|
|
the template parameter instead of the derived one.
|
|
|
|
Example:
|
|
|
|
.. code-block:: c++
|
|
|
|
template <typename T> class CRTP {
|
|
protected:
|
|
CRTP() = default;
|
|
};
|
|
|
|
class Good : CRTP<Good> {};
|
|
Good GoodInstance;
|
|
|
|
class Bad : CRTP<Good> {};
|
|
Bad BadInstance;
|
|
|
|
To ensure that no accidental instantiation happens, the best practice is to
|
|
make the constructor private and declare the derived class as friend. Note
|
|
that as a tradeoff, this also gives the derived class access to every other
|
|
private members of the CRTP. However, constructors can still be public or
|
|
protected if they are deleted.
|
|
|
|
Example:
|
|
|
|
.. code-block:: c++
|
|
|
|
template <typename T> class CRTP {
|
|
CRTP() = default;
|
|
friend T;
|
|
};
|
|
|
|
class Good : CRTP<Good> {};
|
|
Good GoodInstance;
|
|
|
|
class Bad : CRTP<Good> {};
|
|
Bad CompileTimeError;
|
|
|
|
CRTP<int> AlsoCompileTimeError;
|
|
|
|
|
|
Limitations
|
|
-----------
|
|
|
|
* The check is not supported below C++11
|
|
|
|
* The check does not handle when the derived class is passed as a variadic
|
|
template argument
|
|
|
|
* Accessible functions that can construct the CRTP, like factory functions
|
|
are not checked
|
|
|
|
The check also suggests a fix-its in some cases.
|
|
|