我使用以下代码获得了最新版本的clang和gcc的错误:
int main() {
auto lambda = [] (auto = [] {}) {};
lambda();
}
Run Code Online (Sandbox Code Playgroud)
Clang给出错误:
prog.cc: In function 'int main()':
prog.cc:3:12: error: no match for call to '(main()::<lambda(auto:1)>) ()'
lambda();
^
prog.cc:2:35: note: candidate: template<class auto:1> main()::<lambda(auto:1)>
auto lambda = [] (auto = [] {}) {};
^
prog.cc:2:35: note: template argument deduction/substitution failed:
prog.cc:3:12: note: couldn't deduce template parameter 'auto:1'
lambda();
^
Run Code Online (Sandbox Code Playgroud)
为什么这会失败?
Dan*_*rey 22
类型推导auto不考虑默认参数.
Den*_*rim 11
由于lambdas是仿函数的糖,因此问题在于模板函数无法auto在此默认上下文中推导出模板参数().
通过考虑这些语句,lambda可以简化为functor结构级别:
§5.1.2/ 3 [expr.prim.lambda]
lambda表达式的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型[...]
§5.1.2/ 5 [expr.prim.lambda]
[...]对于通用lambda,闭包类型有一个公共内联函数调用操作符成员模板(14.5.2),其template-parameter-list包含一个发明的类型模板参数,用于lambda参数中每次出现的auto -declaration-clause,按照出现的顺序.[...]
因此,lambda的类型等同于这个functor类型:
struct unnamed
{
template<typename Auto1>
auto operator()(Auto1 = []{})
{
}
};
Run Code Online (Sandbox Code Playgroud)
然后你的用法相当于:
int main() {
auto lambda = unnamed();
lambda();
}
Run Code Online (Sandbox Code Playgroud)
根据§14.8.2.5/ 5 [temp.deduct.type]中的Auto1规定,无法在此上下文中推断出类型:
未推断的上下文是:
[...]
- 在函数参数的参数类型中使用的模板参数,该参数具有在正在进行参数推断的调用中使用的默认参数.
| 归档时间: |
|
| 查看次数: |
1095 次 |
| 最近记录: |