Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ decltype(自动)从lambda捕获推断出的返回类型_C++_C++11_Lambda_C++14_Decltype - Fatal编程技术网

C++ decltype(自动)从lambda捕获推断出的返回类型

C++ decltype(自动)从lambda捕获推断出的返回类型,c++,c++11,lambda,c++14,decltype,C++,C++11,Lambda,C++14,Decltype,我有一些编译器不同意一个小的C++14代码段: #include <cassert> struct unmovable { unmovable() {} unmovable(unmovable&&) = delete; }; int main() { unmovable u; auto i = [&]() -> decltype(auto) { return u; }; auto& uu = i(); assert

我有一些编译器不同意一个小的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);
}
然后所有编译器都接受它,不管
u
是全局的还是局部的,我认为这加强了我对
decltype(auto)
推断的解释,因为
v
在这里肯定变成了
不可移动的类型&


我的解释正确吗?因此,铿锵++不正确吗?

在我看来,铿锵似乎是正确的。我同意您的解释,即lambda返回类型必须是
decltype(u)
,但不是
decltype(u)
不可移动的&

5.1.2 Lambda表达式[expr.prim.Lambda]

18 lambda表达式的component语句中的每个id表达式都是 副本捕获的实体被转换为对副本的相应未命名数据成员的访问 闭合类型。[注意:非odr用途的id表达式引用原始实体,而不是闭包类型的成员。此外,此类id表达式不会导致实体的隐式捕获。 --结束说明][…]

19每次出现
decltype((x))
where[…]

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

p18接着说,由于
decltype(u)
中的
u
不是odr用法,它指的是原始实体,因此不会转换为闭包类型成员的访问

然而,第19页明确指出,如果您将
return
语句编写为

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

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

在lambda中,
decltype(u)
指的是捕获的实体,而不是闭包的任何数据成员。参见[expr.prim.lambda]p19,但gcc的行为似乎不一致:@dyp[expr.prim.lambda]p19是关于
decltype((u))
,而不是关于
decltype(u)
decltype
是一种罕见的情况,在这种情况下,看似多余的括号可以起到作用。@hvd Yes,[expr.prim.lambda]p19是关于
decltype((u))
,但它增加了特殊处理。如果没有这个特殊规则,
decltype(u)
不是
u
的odr用法,也会引用捕获的实体。编辑-阅读您的答案后,我们似乎同意;所以这只是一个误解?另一点:根据,创建非静态数据成员甚至不需要通过引用捕获,因此
decltype
不可能引用这样的成员。我同意这一点,但是,为什么可选的lambda
[](auto&v)->decltype(auto){return v;}
为所有尝试的编译器返回左值引用?@rollbear,因为它作用于声明的
v
类型,而不是声明的
u
类型
v
被声明为引用类型,
u
不是。我所追求的行为仅仅是理解,因为我需要记录它。嘿,哇。我们刚刚讨论了通过复制捕获引用是捕获引用还是捕获副本。。。这一切都是因为诊断是
decltype()
等。-这不是odr使用,返回的是外部对象的类型-不是相同名称的副本。改变捕获名单中的名字暗示了一个令人惊讶的事实。。。然后我举世闻名的谷歌搜索能力把我带到了你们举世闻名的回答能力
auto i = [&]() -> decltype(auto) { return (u); };