如果lambdas包含多个语句,那么不允许它推导返回类型有什么原因吗
Is there a reason on not allowing lambdas to deduce the return type if it contains more than one statement?
取自C++0x FDIS(n3290):
如果lambda表达式不包括lambda声明符,则该lambda声明器就好像是()。如果lambda表达式不包括尾部返回类型,则尾部返回类型表示以下类型:
- 如果复合语句的形式为
{属性说明符seqopt返回表达式;}
左值到右值转换(4.1)、数组到指针转换后返回的表达式的类型(4.2)和函数-指针转换(4.3)- 否则无效
为什么标准不允许编译器根据第一个找到的return
语句来分析复合语句并确定返回类型?
我看不出有什么理由不允许这样做,但也许我忽略了什么。
示例:
int main(){
// compiler: nope.jpg
auto l = []{
// one computation
// another computation
// yet another one!
return something;
}
}
编辑:请不要回答"因为标准这么说"。:)
这没有技术原因。IIRC它已经由GCC C++维护人员实现了,他说实现起来很简单。
委员会在接受标准中的特征方面非常保守,所以他们采用了这种简单的推导形式,希望以后能接受一种更强大的形式。请参阅美国30号评论中拒绝的原因。
DR 975已经标记为"准备就绪",因此很有可能被接受。
Why doesn't the standard allow the compiler to analyse the compound-statement and determine the return type based on the first found return statement?
在我看来,原因是继承、对void*
的隐式类型转换和0
对int
的类型转换,这使得编译器实现者很难从第一个return
语句推导类型。参见以下示例:
// "B" is a derived by "D"
int main(){
auto l = []{
return (D*)(...); // should it be "D*" (derived)
// computation
return (B*)(...); // no it should be "B*" (base)
}
}
第二,
int main(){
auto l = []{
return (int*)(...); // should it be "int*"
// computation
return (void*)(...); // no it has to be "void*"
}
}
第三,
int main(){
auto l = []{
return 0; // should it be "int"
// computation
return (double)(...); // no it has to be "double"
}
}
此外,当发现两个不相关的return
时,还有一个原因与发出编译错误消息有关:
int main(){
auto l = []{
return TYPE1;
// computation
return TYPE2;
}
}
现在,问题来了,什么有用的编译器消息应该打印给用户?错误消息必须仅针对其中一个return
语句。选择哪个return
?
我认为这不是一个限制,而是一个允许在身体只有return expression
时省略-> decltype(expression)
。很明显,在这种情况下返回的类型是什么。
你的建议需要编译器做更多的工作,也需要我们程序员做更多的规则。它能给我们买很多东西吗?
我想是因为这种代码:
void foo( bool k )
{
auto call= [](){ if( k ) return 42; else return 'c'; }; // what is the return type?
call();
}
这里的返回类型可以是int或char。由于这些类型中的每一种都可以隐含地转换为另一种,因此编译器无法猜测返回类型是什么。因此,为了避免混淆或避免编译器实现决定它应该是什么类型,调试人员只需告知这将产生一个错误(诊断),允许程序员指定需要什么类型。
因此,这只是为了确保编译器不会编译过于模糊的代码,从而不允许猜测返回类型。
- 返回类型在 C++ OOP 中是什么意思
- 对于具有引用返回类型的搜索算法,默认返回值应该是什么?
- T*&返回类型到底是什么
- 虚函数如何工作,分配后新的返回类型会发生什么?
- 运算符和返回类型是什么意思?
- 作为返回类型"const int&"做什么?
- STD :: SETW,STD :: SETFILL等的真实返回类型是什么?
- const 在具有尾随返回类型的自动退货声明中是什么意思
- C++协方差返回类型的缺点是什么
- 尾随返回类型中的占位符类型的用途是什么
- 从具有引用返回类型的函数返回什么
- C++中以下函数的返回类型是什么
- 此函数的返回类型是什么
- 提升的返回类型是什么::apply_visitor(延迟版本)
- C 中构造函数的返回类型是什么
- T const & 在函数的返回类型中是什么意思?
- 作为返回类型的枚举关键字的存在表明什么
- 什么是布尔维纳皮返回类型
- 如果返回了向量的一个项,lambda表达式的返回类型是什么
- 当函数返回值是指针,而返回类型是c++中的引用时会发生什么