为什么C++中的拉姆达从来没有缺省构造
[](){};
我有一个模板类,它包含这样的拉姆达。由于lambda不包含非静态数据成员,也不包含虚函数,因此它应该是一个空类和DefaultConstructible。它只是一种可用于模板元编程的策略类。我想知道,为什么这样的类不是C++标准默认构造的。
旁注:Understanding how Lambda closure type has deleted default constructor提出了一个不同的问题,虽然标题似乎非常相似。它问如何在没有可用的默认构造函数的情况下创建一个无状态的lambda对象。我在问为什么没有可用的默认构造函数。
Lambdas旨在创建然后使用。标准因此说“不,他们没有默认的构造函数”。唯一的办法是通过一个lambda表达式或者相同的副本。
他们是而不是意欲为他们的类型是你保留和使用的东西。这样做可能会违反ODR的规定,并且要求编译器避免ODR违规,这会使符号过度复杂化。
然而,在C++ 17你可以写身边一个函数指针无国籍包装:
template<auto fptr>
struct function_pointer_t {
template<class...Args>
// or decltype(auto):
std::result_of_t< std::decay_t<decltype(fptr)>(Args...) >
operator()(Args&&...args)const
return fptr(std::forward<Args>(args)...);
}
};
随着operator void(*)()
上[](){}
是constexpr
在C++ 17,function_pointer_t<+[](){}>
是一个什么都不做的函数对象那就是DefaultConstructible。
这实际上并不包含lambda,而是lambda产生的指针函数。
'''function_pointer_t '中的'+'是故意的,如果是这样的话,意味着什么? –
@ PeterA.Schneider它[将空捕获组的lambdas转换为函数指针。](http://*.com/questions/18889028/a-positive-lambda-what-sorcery-is-this) – jaggedSpire
好吧,我试过了你的解决方案但是我有了C++ 17可用,它不起作用。首先它偶然发现'template
我假设你熟悉类型,对象和表达式之间的区别。在C++中,λλ具体指的是λ表达式。这是一个方便的方式来表示一个非平凡的对象。但是,它很方便:您可以通过编写代码自己创建一个类似的对象。
现在,根据C++规则,每个表达式都有一个类型,但该类型不是lambda表达式的目的。这就是为什么它是一个未命名和独特的类型--C++委员会认为不值得定义这些属性。同样,如果它被定义为具有默认ctor,则标准应定义该行为。根据目前的规则,不需要定义默认ctor的行为。
正如你所注意到的,对于[](){}
的特殊情况,定义一个默认ctor是很简单的。但这没有意义。你马上就会遇到第一个难题:为什么lambda应该定义默认的ctor?什么lambda的子集足够简单,有一个体面的定义,但足够复杂,有趣?没有一致意见,你不能期望这是标准化的。
请注意,作为扩展的编译器供应商已经可以提供此功能。标准化通常遵循现有的做法,参见Boost。但是,如果没有编译器供应商个人认为这是值得的,他们为什么一致认为这么做?
实际上,您可以将lambda看作是一个对象,它是由将捕获列表作为构造函数参数的构造函数创建的。具有空捕获列表的lambda自然应该有一个默认的构造函数恕我直言。 –
[This question](http:// *。com/questions/32911729/understanding-how-lambda-closure-type-has-deleted-default-constructor)可能是相关的。 –
你会如何默认构建一个lambda? '[] {}'已经构造出一个并给你实例。 – rustyx
@rustyx像这样:'auto f =()[] {};使用f_t = decltype(f); f_t {};' - 这有效,但是因为lambda已经删除了默认的构造函数。 –