gpt4 book ai didi

c++ - decltype(auto) 从 lambda 捕获中推导出返回类型

转载 作者:可可西里 更新时间:2023-11-01 16:38:40 31 4
gpt4 key购买 nike

我有编译器不同意一个小的 C++14 代码片段:

#include <cassert>

struct unmovable {
unmovable() {}
unmovable(unmovable&&) = delete;
};

int main()
{
unmovable u;

auto i = [&]() -> decltype(auto) { return u; };
auto& uu = i();

assert(&uu == &u);
}

该程序被 g++4.9.3、g++-5.1.0、g++-5.2.0 和 VisualStudio 2015 接受,但不被 clang++-3.7 接受。

clang++-3.7 推断返回类型为unmovable(值)而不是unmovable&

如果程序稍作改动,变量 u 是全局变量,那么所有编译器都会同意这个错误。

据我了解,当变量是本地变量时,lambda 中捕获的 u 应该是 unmovable& 类型。

我没有 C++14 标准,但希望来自 github 的草案是相关的。我对 7.1.6.2 和 7.1.6.4 的解释是 decltype(auto) 从 return 变成了 decltype(u),在全局情况下应该是 unmovable (value) 并且在本地 u 的 lambda 引用捕获中,它应该变为 unmovable& 因为捕获的变量必须是类型 unmovable&。这表明 clang++ 弄错了。

如果我稍微更改 lambda 及其用法:

auto i = [](auto& v) -> decltype(auto) { return v; };
auto& uu = i(u);

然后所有编译器都接受它,无论 u 是全局的还是局部的,我认为这加强了我对 decltype(auto) 推论的解释,因为 v 这里肯定变成了 unmovable& 类型。

我的解释是否正确,因此 clang++ 不正确?

最佳答案

clang 对我来说似乎是正确的。我同意您的解释,即 lambda 返回类型必须是 decltype(u),但不是 decltype(u)unmovable&

5.1.2 Lambda expressions [expr.prim.lambda]

18 Every id-expression within the compound-statement of a lambda-expression that is an odr-use (3.2) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. [ Note: An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type. Furthermore, such an id-expression does not cause the implicit capture of the entity. -- end note ] [...]

19 Every occurrence of decltype((x)) where [...]

p19 不适用,因为你有 decltype(u),而不是 decltype((u))

p18 然后说 decltype(u) 中的 u 不是 odr-use,它指的是原始实体,它不会转换为访问闭包类型的成员。

但是,p19 明确指出,如果您将 return 语句写为

auto i = [&]() -> decltype(auto) { return (u); };

然后 lambda 将通过引用返回 u。如果这是您想要的行为,这将适用于 clang。

关于c++ - decltype(auto) 从 lambda 捕获中推导出返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33854388/

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