我认为以下代码非常方便且无害:
auto fn = [](bool b = false) -> int // NOT legal in C++11
{
return b ? 1 : 0;
};
为什么 C++11 明确禁止 lambda 表达式的默认参数?
我只是想知道背后的理由和考虑。
我想知道 C++11 标准所说的“为什么”而不是“什么”。
原文由 xmllmx 发布,翻译遵循 CC BY-SA 4.0 许可协议
我认为以下代码非常方便且无害:
auto fn = [](bool b = false) -> int // NOT legal in C++11
{
return b ? 1 : 0;
};
为什么 C++11 明确禁止 lambda 表达式的默认参数?
我只是想知道背后的理由和考虑。
我想知道 C++11 标准所说的“为什么”而不是“什么”。
原文由 xmllmx 发布,翻译遵循 CC BY-SA 4.0 许可协议
正如对该问题的评论所暗示的那样,可能没有 技术上 的理由不存在默认参数。但另一个问题是“默认参数有 实际 原因吗?”我认为这个问题的答案是“不”,这就是原因。
为了调用 lambda,您可以做的一件事是立即调用它
[] { printf("foo"); }();
我敢肯定这有有限的用途,如果有的话,所以让我们继续。调用 lambda 的唯一另一种方法是首先将其绑定到变量,这里有几个选项。
auto foo = [] { printf("foo"); }; foo();
void (*foo)() = [] { printf("foo"); }; foo()
。当然,这仅在 lambda 未捕获时才有效。现在让我们来看看默认参数在每种情况下的用处
我认为这些点足以说明 lambda 的默认参数真的没那么有用。另外,我看到有些人在谈论 lambda 类型的问题,如果它有默认参数,但这是一个非 IMO 问题。您始终可以编写自己的仿函数来执行相同的操作,并且 确实 具有默认参数。另外,关于降级为函数指针,也没什么好说的。取正常功能
void func(int i = 0)
{
}
并把它的地址。你得到了什么? void (*)(int)
。没有理由 lambda 会遵循不同的规则。
原文由 Ken Wayne VanderLinde 发布,翻译遵循 CC BY-SA 3.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
没有真正的理由 lambda 不能有默认参数。但是,使用 lambda 有两种主要方法,其中只有一种允许默认参数而不更改类型系统。
您可以直接调用 lambda,也可以通过模板调用。在这种情况下,默认参数可以正常工作。
您可以通过
std::function
调用 lambda。如果不更改类型系统,默认参数将不起作用。我的猜测是人们用 C++11 编写的新函数 通常会 采用
std::function
参数,因为这样,函数 不必 是模板,也不必实例化每个传递给它的 lambda 和仿函数。为什么
std::function
(或函数指针)不能采用默认值?这种函数的类型并不明显。
如果是
std::function<int(bool)>
,那么您如何使用默认值调用它? (你不能。)如果是
std::function<int(bool=false)>
,那么它兼容哪些类型,转换如何工作?你能把它转换成std::function<int()>
吗?std::function<int(bool=true)>
怎么样?如果是
std::function<int(bool=default)>
之类的新东西, 那么 它与哪些类型兼容,转换如何工作?基本上,这不仅仅是您可以在标准中翻转并制作函数指针/
std::function
处理默认参数的开关。普通函数中的默认参数是使用函数声明中的信息处理的,这些信息在 lambda 或函数指针的调用站点不可用。因此,您必须将有关默认值的信息编码到函数类型中,然后为转换和兼容性制定所有非显而易见的规则。因此,您必须提出一个令人信服的理由来 说明为什么 要添加这样的功能,并说服委员会。
那么,为什么 lambda 不能采用默认值呢?
我没有回答这个问题。但我认为添加它不会是一个非常有用的功能。如果可以的话,我会删除这个答案,但它已被接受。如果可以的话,我会投反对票,但这是我的。这就是生活。