66 lines · plain
1.. title:: clang-tidy - bugprone-forwarding-reference-overload2 3bugprone-forwarding-reference-overload4======================================5 6The check looks for perfect forwarding constructors that can hide copy or move7constructors. If a non const lvalue reference is passed to the constructor, the8forwarding reference parameter will be a better match than the const reference9parameter of the copy constructor, so the perfect forwarding constructor will10be called, which can be confusing.11For detailed description of this issue see: Scott Meyers, Effective Modern C++,12Item 26.13 14Consider the following example:15 16.. code-block:: c++17 18 class Person {19 public:20 // C1: perfect forwarding ctor21 template<typename T>22 explicit Person(T&& n) {}23 24 // C2: perfect forwarding ctor with parameter default value25 template<typename T>26 explicit Person(T&& n, int x = 1) {}27 28 // C3: perfect forwarding ctor guarded with enable_if29 template<typename T, typename X = enable_if_t<is_special<T>, void>>30 explicit Person(T&& n) {}31 32 // C4: variadic perfect forwarding ctor guarded with enable_if33 template<typename... A,34 enable_if_t<is_constructible_v<tuple<string, int>, A&&...>, int> = 0>35 explicit Person(A&&... a) {}36 37 // C5: perfect forwarding ctor guarded with requires expression38 template<typename T>39 requires requires { is_special<T>; }40 explicit Person(T&& n) {}41 42 // C6: perfect forwarding ctor guarded with concept requirement43 template<Special T>44 explicit Person(T&& n) {}45 46 // (possibly compiler generated) copy ctor47 Person(const Person& rhs);48 };49 50The check warns for constructors C1 and C2, because those can hide copy and51move constructors. We suppress warnings if the copy and the move constructors52are both disabled (deleted or private), because there is nothing the perfect53forwarding constructor could hide in this case. We also suppress warnings for54constructors like C3-C6 that are guarded with an ``enable_if`` or a concept,55assuming the programmer was aware of the possible hiding.56 57Background58----------59 60For deciding whether a constructor is guarded with enable_if, we consider the61types of the constructor parameters, the default values of template type parameters62and the types of non-type template parameters with a default literal value. If any63part of these types is ``std::enable_if`` or ``std::enable_if_t``, we assume the64constructor is guarded.65 66