是我的书吗;s对lambda返回类型的讨论是错误的
Is my book's discussion of lambda return types wrong?
我的书是这样说的:
函数体包含除单个返回语句之外的任何内容的Lambdas,这些语句不指定返回类型return void。
但是这个:
auto f = []{
int i=0; i++;
return std::string("foo");
};
std::cout << f() << std::endl;
实际上编译并打印出"foo",但lambda-expr不仅仅有一个返回语句,因此它应该返回void,因为它没有手动指定"->std::string"作为返回类型。
这是怎么回事?
我在最新的Xcode 4.6中使用了苹果的编译器,它似乎是基于Clang 3.2的:
clang—版本
Apple LLVM 4.2版(clang-425.0.24)(基于LLVM 3.2svn)目标:x86_64-apple-darwin12.2.0线程模型:posix
本书准确地反映了本标准草案n3290中的规则。也许您的编译器实现了不同的草稿。
在第5.1.2p4节中,草案显示
如果lambda表达式不包含尾部返回类型,则为就好像尾部返回类型表示以下类型:
- 如果复合语句的形式
{
属性说明符seqoptreturn
表达式;
}
左值到右值转换、数组到指针转换和函数到指针转换后返回的表达式的类型- 否则无效
语法结构属性说明符seq可以是alignas
或双括号属性。非变量声明。
n3485草案是在C++11发布之后提出的(即它正在朝着C++1y的方向发展),包含了相同的措辞。我不知道在n3290之前的一些草案中是否有不同的规则。
如果使用流行的编译器(gcc、Visual Studio),通常不需要指定返回类型,只要编译器能够明确地确定它即可,就像您的示例中一样。
以下示例显示了一个lambda,它需要显式的返回类型信息:
auto lambda = [](bool b) -> float
{
if (b)
return 5.0f;
else
return 6.0;
};
我就此事询问了Bjarne Stroustrup,他的评论是:
I do not know if C++11 allows the deduction of the return type is there are several return statements with identical return type. If not, that's planned for C++14.
我不确定该从问题中的引号中得到什么,但以下是C++11标准对没有声明符或返回类型的lambdas的说明:
如果lambda表达式不包括lambda声明符,则为如果lambda声明符是()。如果lambda表达式没有包含尾随返回类型,就好像尾随返回类型表示以下类型(5.1.2p4):
--如果复合语句的形式为{属性说明符seqopt返回表达式;}在左值到右值转换后返回表达式(4.1),数组到指针转换(4.2)和函数到指针转换(4.3);
--否则无效。
Clang实现了对C++核心问题975的拟议解决方案。这允许lambda的任意主体,带有任意数量的返回语句,并根据返回的表达式推导返回值,条件是它们必须都产生相同的类型。
在C++14中,N3638进一步推广了这一支持,该支持在WG21的布里斯托尔会议上被投票纳入了该标准的工作草案。
Draft n3485表示,如果编译器能够明确地确定返回类型,则允许lambda不指定它。
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- C++中函数的向量返回类型引发错误
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- LibClang clang_getArgType() 返回错误的类型
- 错误:为"运算符 std::string {aka std::__cxx11::basic_string}"指定的返回类型<char>
- 尝试使用具有尾随返回类型的 lambda 进行 SFINAE 时出现硬错误
- 错误:控制到达非空函数的末尾 [-Werror=返回类型] } ^
- 尾随返回类型中带有 SFINAE 的 GCC 错误
- 返回类型布尔函数中的声明语法错误
- C++:在原型中声明"auto"函数返回类型仍然会导致在扣除错误之前使用"auto&quo
- 带有返回类型的错误调用模板到会员函数
- 错误:返回类型 'class Polar' 不完整,无效使用类型 'polar'
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- 错误:"运算符="不匹配 |结构返回类型
- typedef映射作为返回类型到函数会引发编译器错误
- 协变返回类型无效的转换错误
- C 函数返回类型错误
- 模板成员函数具有尾随返回类型,即使未使用也会出现错误