decltype 错误 C2440 无法从'int *'转换为'int *&'

decltype error C2440 cannot convert from 'int *' to 'int *&'

本文关键字:int 转换 decltype C2440 错误      更新时间:2023-10-16

以下是实际代码的一个人为示例:

int** Ptr = 0;
decltype(Ptr[0]) Test = (int*)0;

我得到错误:

错误C2440:"initializing":无法从"int*"转换为"int*&"

我不知道为什么会这样,因为根据我对decltype的理解(如果我错了,请纠正我),它只需要你给它的任何表达式,并将其解析为它的实际类型。在这种情况下,Ptr[0]int*,所以我期待:int* Test = (int*)0;

我错过了什么?为什么我会犯那个错误?

如果我们进入C++标准草案7.1.6.2简单类型说明符[dcl.type.Simple],看看有什么情况,对于decltype,它一开始说:

对于表达式e,decltype(e)表示的类型定义如下:

我们看到,在这种情况下,表达式既不是id表达式,也不是类成员访问,这将给出您期望的结果(emphasis mine):

  • 如果e是一个未加括号的id表达式或一个未带括号的类成员访问(5.2.5),则decltype(e)是由e命名的实体的类型。如果不存在这样的实体或者如果e命名一组重载函数,程序格式不正确

但结果是一个左值:

  • 否则,如果e是左值,则decltype(e)是T&,其中T是e的类型

这导致参考。

正如M.M所指出的,std::remove_reference可以用于获得您想要的结果:

std::remove_reference<decltype(Ptr[0])>::type Test = (int*)0;

正如T.C.所指出的,std::衰变也是一种选择,并且更短:

std::decay<decltype(Ptr[0])>::type Test = (int*)0;

除了所有其他答案外,您还可以只使用

int ** ptr = 0;
decltype(+ptr[0]) test = (int*)0;
// (+*p) is now an r-value expression of type int, rather than int&

这里使用的一些规则是:

  • 如果表达式的值类别是左值,则decltype产生T&
  • 如果表达式的值类别是prvalue,则decltype产生T

还要注意的是,如果对象的名称用括号括起来,它将被视为一个普通的左值表达式,因此decltype(x)和declttype((x))通常是不同的类型。[摘录自https://en.cppreference.com/w/cpp/language/decltype]

在http://www.cplusplus.com/forum/beginner/149331/
有关decltype的更多信息,请点击此处:https://en.cppreference.com/w/cpp/language/decltype