bugprone-forwarding-reference-overload

该检查查找可能隐藏复制或移动构造函数的完美转发构造函数。如果将非 const 左值引用传递给构造函数,则转发引用参数将比复制构造函数的 const 引用参数更匹配,因此将调用完美转发构造函数,这可能会令人困惑。有关此问题的详细说明,请参阅:Scott Meyers,Effective Modern C++,第 26 条。

请考虑以下示例

class Person {
public:
  // C1: perfect forwarding ctor
  template<typename T>
  explicit Person(T&& n) {}

  // C2: perfect forwarding ctor with parameter default value
  template<typename T>
  explicit Person(T&& n, int x = 1) {}

  // C3: perfect forwarding ctor guarded with enable_if
  template<typename T, typename X = enable_if_t<is_special<T>, void>>
  explicit Person(T&& n) {}

  // C4: variadic perfect forwarding ctor guarded with enable_if
  template<typename... A,
    enable_if_t<is_constructible_v<tuple<string, int>, A&&...>, int> = 0>
  explicit Person(A&&... a) {}

  // C5: perfect forwarding ctor guarded with requires expression
  template<typename T>
  requires requires { is_special<T>; }
  explicit Person(T&& n) {}

  // C6: perfect forwarding ctor guarded with concept requirement
  template<Special T>
  explicit Person(T&& n) {}

  // (possibly compiler generated) copy ctor
  Person(const Person& rhs);
};

该检查会对构造函数 C1 和 C2 发出警告,因为它们可能隐藏复制和移动构造函数。如果复制和移动构造函数都被禁用(删除或私有),我们会抑制警告,因为在这种情况下,完美转发构造函数不会隐藏任何内容。我们还会对像 C3-C6 这样的构造函数抑制警告,这些构造函数使用 enable_if 或概念进行保护,假设程序员意识到了可能的隐藏。

背景

为了确定构造函数是否使用 enable_if 进行保护,我们考虑构造函数参数的类型、模板类型参数的默认值以及具有默认字面值的非类型模板参数的类型。如果这些类型中的任何一部分是 std::enable_ifstd::enable_if_t,我们假设构造函数受到保护。