当前位置: 首页 > 知识库问答 >
问题:

为什么不能形成对“decltype(auto)”的引用

上官高逸
2023-03-14
int main(){
    decltype(auto)&& a = 100;
}

上面的代码,GCC中的一个错误和叮当声。

int main(){
    decltype(int)&& a = 100;
}

这个代码是正确的。

在N4296中,

在§8.3.2/6中

如果typedef(7.1.3)、类型模板参数(14.3.1)或decltype说明符(7.1.6.2)表示引用类型T的类型TR,则尝试创建类型“对cv TR的左值引用”将创建类型“对T的左值引用”,而尝试创建类型“对cv TR的右值引用”将创建类型TR。

§7.1.6.2中的decltype说明符

decltype说明符:
  decltype(表达式)
  decltype(自动)

我认为§8.3.2/6的措辞有问题。

为什么不允许引用decltype(auto)。请告诉我相关标准的措辞。抱歉用蹩脚的英语说。非常感谢。

共有1个答案

莫泓
2023-03-14

在7.1.6.4[dcl.spec.auto]

如果占位符是decltype(auto)类型说明符,则变量的声明类型或函数的返回类型应仅为占位符。根据7.1.6.2中的描述确定为变量或返回类型推导的类型,就像初始值设定项是decltype的操作数一样。

所以这是允许的:

decltype(auto) a = 100;

但不是这个:

decltype(auto)& a = 100;

或者这个:

decltype(auto)&& a = 100;

这是有道理的,因为dectype(auto)背后的想法之一是在类型推导过程中保留引用性(即使用dectype类型推导,而不是模板/自动类型推导)

该标准为我们提供了一些示例,说明如何通过decltype(auto)推断引用:

int i;
int&& f();
auto x3a = i;                  // decltype(x3a) is int
decltype(auto) x3d = i;        // decltype(x3d) is int
auto x4a = (i);                // decltype(x4a) is int
decltype(auto) x4d = (i);      // decltype(x4d) is int&
auto x5a = f();                // decltype(x5a) is int
decltype(auto) x5d = f();      // decltype(x5d) is int&&
auto x6a = { 1, 2 };           // decltype(x6a) is std::initializer_list<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i;                // decltype(x7a) is int*
decltype(auto)*x7d = &i;       // error, declared type is not plain decltype(auto)
 类似资料:
  • 泛型lambda(generic lambdas)是C++14中最值得期待的特性之一——因为在lambda的参数中可以使用auto关键字。这个特性的实现是非常直截了当的:即在闭包类中的operator()函数是一个函数模版。例如存在这么一个lambda: auto f = [](auto x){ return func(normalize(x)); }; 对应的闭包类中的函数调用操作符看来就变

  • 在里面https://github.com/stlab/libraries/blob/main/stlab/concurrency/main_executor.hpp,我读到 decltype(f)的意义是什么,为什么不直接使用f?

  • 问题内容: 我正在向我的朋友解释OOP。我无法回答这个问题。(我有多可耻? 我只是想逃避,因为OOP描绘了现实世界。在现实世界中,父母可以容纳孩子,但孩子不能容纳父母。OOP也是如此。我知道它很愚蠢。:P 为什么此陈述无效? 因为aChild的成员是aParent成员的超集。那为什么孩子不能容纳父母。 问题答案: 正是因为aChild是aParent功能的超集。你可以写: 因为每只狐狸都是动物。但

  • 考虑一个例子: 在这个简单的例子中,clang(输出:)和gcc(输出:)不一致。

  • 当然,现在只能检测带有0个参数的函数。为什么在使用时正确选择了专门化,而不是?

  • 我了解在lambda中捕获此(修改对象属性)的正确方法如下: 但我对我所看到的以下特点感到好奇: 我感到困惑(并希望得到回答)的奇怪之处在于,为什么以下方法有效: 以及为什么我无法通过引用明确捕获此内容: