gpt4 book ai didi

c++ - 如何在 C++14 中编写通用转发 lambda?

转载 作者:IT老高 更新时间:2023-10-28 22:28:21 27 4
gpt4 key购买 nike

如何在 C++14 中编写通用转发 lambda?

尝试#1

[](auto&& x) { return x; }

在函数体内,x是一个左值,所以这不起作用。

尝试#2

[](auto&& x) { return std::forward<decltype(x)>(x); }

这会在 lambda 中正确转发引用,但它总是会返回 按值(除非编译器省略了拷贝)。

尝试#3

[](auto&& x) -> decltype(x) { return std::forward<decltype(x)>(x); }

这将返回与参数相同的类型(可能 -> auto&& 也可以)并且似乎可以正常工作。

尝试#4

[](auto&& x) noexcept -> decltype(x) { return std::forward<decltype(x)>(x); }

添加 noexcept 是否会使这个 lambda 更适用,从而严格优于 #3?

最佳答案

decltype(x)的返回类型不足。

值取的局部变量和函数参数可以隐式移入返回值,但右值引用取的函数参数不能(x是左值,即使decltype(x) == rvalue如果您传递一个右值,请引用)。委员会给出的理由是,他们想确定当编译器隐式移动时,其他人不可能拥有它。这就是为什么我们可以从纯右值(一个临时的、非引用限定的返回值)和函数局部值转移。但是,有人可以做一些愚蠢的事情,比如

std::string str = "Hello, world!";
f(std::move(str));
std::cout << str << '\n';

并且委员会不想默默地调用一个不安全的举动,认为他们应该从这个新的“举动”功能开始更加保守。请注意,在 C++20 中,此问题将得到解决,您只需执行 return x 即可。见 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0527r0.html

对于转发功能,我会尝试让 noexcept 正确。在这里很容易,因为我们只是在处理引用(它是无条件的noexcept)。否则,你会破坏关心 noexcept 的代码。

这使得最终的理想转发 lambda 如下所示:

auto lambda = [](auto && x) noexcept -> auto && { return std::forward<decltype(x)>(x); };

decltype(auto) 的返回类型在这里会做同样的事情,但是 auto && 更好地证明了这个函数总是返回一个引用。它还避免了再次提及变量名称,我想这会使重命名变量稍微容易一些。

从 C++17 开始,转发 lambda 在可能的情况下也是隐式 constexpr。

关于c++ - 如何在 C++14 中编写通用转发 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30091288/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com