为什么从可变参数继承时需要转发构造函数参数?

Why need to forward constructor parameters when inheriting from variadic arguments?

我知道标题完全没有意义,我正在挑战你根据问题编辑它。
我有以下包装 lambda 表达式(从它们继承)并使用它们的 operator()'s 进行重载。

#include <iostream>

template<typename... F>
struct OverloadSet : public F...
{
    OverloadSet(F&&... f) : F(std::forward<F>(f))...{}
    using F::operator() ...;
};

template<typename... T>
auto overloads(T...t) {
    return OverloadSet<T...>(std::forward<T>(t)...);
}

auto s = overloads(
    [](int s) {std::cout << typeid(s).name() << " " << s << std::endl; },
    [](double d) {std::cout << typeid(d).name() << " " << d << std::endl; }
);
int main() 
{
    auto s = overloads(
        [](int s) {std::cout<<typeid(s).name()<<" " << s << std::endl; },
        [](double d) {std::cout << typeid(d).name() << " "<< d << std::endl; }
    );
    s(3);
    s(3.2);
}

代码抄自《C++设计模式》一书(强烈推荐)

而且我观察到构造函数参数是多余的,因为我们只需要基数 类 的 operator()'s
所以我做了一个确切的例子,但使用了更温和的构造函数:

OverloadSet(F&&... f) {}

从这一点来看,我很难理解这个程序是否格式错误,因为不同的编译器有不同的反应:

海湾合作委员会 11.2

Output of x86-64 gcc 11.2 (Compiler #1)
In instantiation of 'OverloadSet<F>::OverloadSet(F&& ...) [with F = {<lambda(int)>, <lambda(double)>}]':
required from 'auto overloads(T ...) [with T = {<lambda(int)>, <lambda(double)>}]'
required from here
error: use of deleted function '<lambda(int)>::<lambda>()'

Clang(最新)

error: constructor for 'OverloadSet<(lambda at <source>:16:2),
 (lambda at <source>:17:2)>' must explicitly initialize the base class '(lambda at <source>:16:2)' which does not have a default constructor
            OverloadSet(F&&... f) {}// F(std::forward<F>(f))...{}

MSVC2019(启用 C++20)

Compiles and prints:
int 3
double 3.2

所以问题是:

  1. 程序格式是否正确?
  2. 如果不是,如果我们只使用 operator() 的基础 类,为什么我们需要转发参数?

我猜 lambda 没有默认构造函数。

更像这样:

class A {
  public:
    A(int a) {}
};

class B {
  public:
    B(double b) {}
};

class C : public A, public B {
  public:
    C() {} // error
};