错误,无法在构造函数主体中构造Lambda的副本

Zeb*_*ish 5 c++ lambda templates constructor

在下文中,一种初始化成员的方式被接受,另一种方式是错误。我不明白:

template <typename T>
struct LambdaHolder
{
    LambdaHolder(T lambdaIn) { lambda = lambdaIn; } // This will not work
    LambdaHolder(T lambdaIn) : lambda(lambdaIn) { } // This will work fine
    T lambda;
};


int main()
{
    auto lambda = []() { return 0; };
    LambdaHolder<decltype(lambda) > foo(lambda); // This will work only if the constructor argument is assigned in the initialiser list

// On the other hand
    int(*lambdaPtr)() = lambda; // A function pointer
    LambdaHolder<decltype(lambdaPtr)> foo(lambdaPtr); // Will work either in initialiser list or constructor body

}
Run Code Online (Sandbox Code Playgroud)

我不了解两件事。我知道某些成员必须在成员初始化程序列表中进行初始化,例如引用和const成员。我不明白的是为什么它会让我在初始化程序列表中而不是在构造函数主体中复制lambda。错误是“您无法构造Lambda的副本”。

另外,我能够创建一个指向lambda的指针,并在初始化器列表或构造函数体中初始化该指针。现在,我知道lambda和函数指针不是完全相同的类型,但事实是我认为无捕获的lambda是作为自由函数实现的,这就是为什么可以为其设置普通函数指针的原因,以及认为当作为参数传递时,它肯定会衰减为指针。

基本上,我想对此加以澄清,在构造函数主体中进行初始化还是在初始化器列表之间进行区别?

编辑:就像Whoan指出的那样,我认为lambda的默认构造函数在C ++ 14之前被删除,而在C ++ 14之后不存在。

who*_*oan 4

这是因为lambda不是默认可构造的:

闭包类型不可默认构造。闭包类型具有“已删除 (C++14 之前) | 无 (C++14 起)”默认构造函数。

在这个构造函数中:

LambdaHolder(T lambdaIn) { lambda = lambdaIn; } // This will not work
Run Code Online (Sandbox Code Playgroud)

...lambda在分配之前需要默认构造。