14

-> auto进去有什么用[]() -> auto { return 4; }

对我来说 - 它与[]() { return 4; }

4

1 回答 1

24

auto默认情况下。标准[expr.prim.lambda]/4内容如下:

如果lambda-expression不包含lambda-declarator,则就像lambda-declarator are一样()。lambda 返回类型是,如果提供和/或从[dcl.spec.auto] 中描述的语句推导出来,则将auto其替换为trailing-return-type 。return

我的补充。

所以,-> auto本身是没有用的。但是,我们可以用 形成其他返回类型auto,即:-> auto&, -> const auto&, -> auto&&, -> decltype(auto)。适用退货类型扣除的标准规则。应该记住,auto永远不会被推断为引用类型,因此默认情况下 lambda 返回非引用类型。

一些(微不足道的)例子:

// 1.
int foo(int);
int& foo(char);

int x;

auto lambda1 = [](auto& x) { return x; };
static_assert(std::is_same_v<decltype(lambda1(x)), int>);

auto lambda2 = [](auto& x) -> auto& { return x; };
static_assert(std::is_same_v<decltype(lambda2(x)), int&>);

// 2.
auto lambda3 = [](auto x) { return foo(x); };
static_assert(std::is_same_v<decltype(lambda3(1)), int>);
static_assert(std::is_same_v<decltype(lambda3('a')), int>);

auto lambda4 = [](auto x) -> decltype(auto) { return foo(x); };
static_assert(std::is_same_v<decltype(lambda4(1)), int>);
static_assert(std::is_same_v<decltype(lambda4('a')), int&>);

// 3.
auto lambda5 = [](auto&& x) -> auto&& { return std::forward<decltype(x)>(x); };
static_assert(std::is_same_v<decltype(lambda5(x)), int&>);
static_assert(std::is_same_v<decltype(lambda5(foo(1))), int&&>);
static_assert(std::is_same_v<decltype(lambda5(foo('a'))), int&>);

PiotrNycz 的补充。正如评论中所指出的(归功于@StoryTeller) - 真正的用法是带有 and 的版本,auto&并且const auto&“退化的情况不值得向后弯曲以禁止。”

看:

int p = 7;
auto p_cr = [&]()  -> const auto& { return p; };
auto p_r = [&]()  -> auto& { return p; };
auto p_v = [&]()  { return p; }; 

const auto& p_cr1 = p_v(); // const ref to copy of p
const auto& p_cr2 = p_cr(); // const ref to p
p_r() = 9; // we change p here

std::cout << p_cr1 << "!=" << p_cr2 << "!\n";
// print 7 != 9 !
于 2018-08-29T12:15:09.453 回答