xml*_*lmx 28 c++ lambda default-arguments c++11
我认为以下代码非常方便且无害:
auto fn = [](bool b = false) -> int // NOT legal in C++11
{
return b ? 1 : 0;
};
Run Code Online (Sandbox Code Playgroud)
为什么C++ 11明确禁止lambda表达式的默认参数?
我只是想知道背后的理由和考虑因素.
我想知道"为什么"而不是C++ 11标准所说的"什么".
Die*_*Epp 19
lambda不能有默认参数.但是,使用lambdas有两种主要方法,其中只有一种方法允许默认参数而不更改类型系统.
您可以直接调用lambda,也可以通过模板调用lambda.在这种情况下,默认参数可以正常工作.
你可以通过调用lambda std::function.如果不更改类型系统,默认参数将无法工作.
我的猜测是,人们在编写新的功能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或函数指针.因此,您必须将有关默认值的信息编码到函数类型中,然后计算出所有非显而易见的转换和兼容性规则.
因此,您必须提出一个令人信服的案例,说明为什么要添加这样的功能,并说服委员会.
我没有回答这个问题.但我认为这不是一个非常有用的功能.如果可以的话,我会删除这个答案,但它已经被接受了.如果可以的话,我会贬低它,但这是我的.这就是生活.
我同意在某些情况下允许 lambdas 中的默认参数工作本身没有真正的“技术”限制。它不会破坏您的指针 and ,因为函数的类型不受默认参数的影响。但这也是为什么这不是非常实用的原因。auto
为什么?
因为默认参数虽然是函数签名的一部分,但不是函数类型的一部分:
[C++11: 1.3.17]:
签名
<function> 名称、参数类型列表 (8.3.5) 和封闭的命名空间(如果有)
[注意:签名用作名称修改和链接的基础。——尾注]
[C++11: 8.3.5/6]:[..]返回类型、参数类型列表、引用限定符和cv-qualifier-seq,但不是默认参数 (8.3.6) 或异常规范 (15.4),是函数类型。[注意:在函数指针、函数引用和成员函数指针的赋值和初始化过程中检查函数类型。——尾注]
它们本质上是一块语法糖,由编译器“激活”,能够看到您使用的函数的声明,并在函数调用点注入:
#include <iostream>
void foo(int x = 5)
{
std::cout << x << '\n';
}
int main()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
5默认参数是“可见”。
但是,当您将函数“隐藏”在指针后面时:
int main()
{
void (*bar)(int) = &foo;
bar();
}
Run Code Online (Sandbox Code Playgroud)
too few arguments to function该类型bar是正确的,编译器知道foo有一个默认的,但根本就没有有直接存在于调用点通知编译器的语法bar是bar也foo。当然,在这个微不足道的场景中,它可以通过观察赋值来解决这个问题,但这对于更广泛的论点来说几乎没有理由。
出于同样的原因,仅在调用站点不可见的定义中声明的默认参数几乎无用:
// a.h
void foo(int);
// a.cpp
#include "a.h"
#include <iostream>
void foo(int x = 5)
{
std::cout << x << '\n';
}
// main.cpp
#include "a.h"
int main()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
too few arguments to function我想这就是原因:
[C++11: 8.3.6/4]:[..]不同作用域中的声明具有完全不同的默认参数集。[..]
我们被允许“堆积”类非模板成员函数定义默认参数([C++11 8.3.6/6]); 该示例表明此默认值仍仅适用于同一个 TU,这遵循我们在上面的第二个代码片段中看到的行为。
因此,如果默认参数不是函数类型的一部分,并且必须对调用站点明确可见,那么只有少数人为的极端情况对 lambda 有用,也就是在调用它们时在创建它们的同一范围内,以便编译器可以轻松地找出如何“填充” lambda 调用的默认参数,那么,这有什么意义呢?不是很多,我告诉你。
| 归档时间: |
|
| 查看次数: |
8740 次 |
| 最近记录: |