lambda的返回类型可以通过返回值推导出来,那么为什么函数不能?

Tre*_*key 75 c++ lambda function auto c++11

#include <iostream>

int main(){

    auto lambda = [] {
        return 7;
    };

    std::cout << lambda() << '\n';

}
Run Code Online (Sandbox Code Playgroud)

该程序编译并打印7.
lambda的返回类型基于返回值7推导为整数类型.


为什么普通功能不能实现这一点?

#include <iostream>

auto function(){
    return 42;
}

int main(){

    std::cout << function() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

错误:'function'函数使用'auto'类型说明符而没有尾随返回类型

Mar*_*cia 77

C++ 14具有此功能.您可以通过设置-std=c++1y标志来测试新版本的GCC或clang .

实例

除此之外,在C++ 14中,您还可以使用decltype(auto)(decltype(auto)作为变量的镜像)为您的函数使用decltype语义推导其返回值.

一个例子是转发功能,对此decltype(auto)特别有用:

template<typename function_type, typename... arg_types>
decltype(auto) do_nothing_but_forward(function_type func, arg_types&&... args) {
    return func(std::forward<arg_types>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

通过使用decltype(auto),您可以模拟func使用指定参数调用时的实际返回类型.在尾随返回类型中没有更多的代码重复,这在C++ 11中非常令人沮丧且容易出错.

  • 为什么`decltype(auto)`而不仅仅是`auto`? (3认同)

Dav*_*eas 25

这只是对语言创建和发展方式的限制.在即将到来的C++ 14标准中,函数的返回类型可以在某些上下文中推导出来,尽管不是全部.有多个return语句时会出现并发症.

另外,推导出的返回类型还有其他问题,例如,模板函数的返回类型不能在SFINAE上下文中使用,因为能够推断出类型,编译器必须实例化替换发生的函数模板.最终结果是,虽然该功能将在不久的将来出现,但如果您可以自己提供该类型,我会避免使用它.

  • *"这只是对语言创建方式和进化方式的限制."* - 当然是单独+1. (5认同)

小智 10

这将在c ++ 14中出现.请参阅以下提案.


Hit*_*ani 6

它还没有..它将在C++ 1y/C++ 14中.查看这个功能的链接


Meh*_*dad 5

我的猜测是,这可能是因为类型推断的lambdas不能递归.

为什么这很重要?因为如果类型推断的lambda可以是递归的(通过"类型推断"我的意思是变量的名称是类型的地方auto),那么它的返回类型可能可能依赖于它自己 - 虽然这有时可以解决,但它很多比"简单"类型推断更难实现.我甚至不确定它是否总是可以解决的(在一般情况下它是否可以判定?).但是,如果函数支持类型推断,则必须考虑此问题,因此可能由于这个原因它们只是将它们排除在外.

  • 允许Lambda和函数是递归的,并且允许变量初始化是自引用的,但是如果存在循环依赖,则"auto"是不正确的. (2认同)
  • 你在这个答案中的断言是递归可能与`auto`一起出现问题.我的回答是这是真的,但他们已经通过简单地禁止你做错事来解决问题.没有理由函数应该与lambdas不同,而在C++ 14中它们不会. (2认同)