【问题标题】:decltype error C2440 cannot convert from 'int *' to 'int *&'decltype 错误 C2440 无法从 'int *' 转换为 'int *&'
【发布时间】:2015-11-09 01:01:03
【问题描述】:

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

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

我得到错误:

错误 C2440:“正在初始化”:无法从“int *”转换为“int *&”

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

我错过了什么?为什么会出现这个错误?

【问题讨论】:

  • 可能Ptr[0] 的类型是左值引用,因此尝试使用纯右值对其进行初始化失败。
  • stackoverflow.com/questions/17241614/… Ptr[0] 的副本已转换为*(Ptr + 0),而decltypedecltype 的内容在上面的链接中进行了解释

标签: c++ decltype


【解决方案1】:

如果我们去草稿 C++ 标准部分 7.1.6.2 简单类型说明符 [dcl.type.simple] 看看是什么情况,对于 decltype 它开始说:

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

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

  • 如果 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::decay 也是一种选择,而且更短:

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

【讨论】:

  • 感谢您的回答。不确定他们以这种方式实施它的原因,对我来说没有意义。有没有办法(演员或任何 C++ shnanigan)让decltype(Ptr[0]) 产生int*? (删除&amp;
  • @vexe 你可以使用std::remove_reference
  • auto 更短:)
  • decay 去掉了 const 限定符,而 remove_reference 没有
【解决方案2】:

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

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

这里使用的一些规则是:

  • 如果表达式的值类别是左值,则 decltype 产生 T&;
  • 如果表达式的值类别是纯右值,则 decltype 产生 T。

还要注意,如果一个对象的名字是带括号的,它被当作一个普通的左值表达式,因此 decltype(x) 和 decltype((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

【讨论】:

  • 如果您添加了关于在 +ptr[0] 中应用的一元 + 运算符如何解决问题的解释,您的答案会好多了
  • @AdrianMole 是的,当然,更新了。谢谢。希望现在解释没问题。
猜你喜欢
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多