首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实化prvalue成员访问的解密类型行为不正确

实化prvalue成员访问的解密类型行为不正确
EN

Stack Overflow用户
提问于 2018-05-16 08:57:00
回答 1查看 71关注 0票数 3
代码语言:javascript
复制
#include <iostream>
#include <type_traits>
 
struct A { double x; };
int main() 
{

    const A && a1 = A();
    
    std::cout << std::is_same_v<decltype((a1.x)), const double&>;
    std::cout << std::is_same_v<decltype((std::move(a1).x)), const double&&>;
    std::cout << std::is_same_v<decltype((A().x)), double>;
   
}

Output:

111

不应该在最后一个例子中解密返回double& last,根据价值范畴的说法。A().x是一个xvalue

X值 a.m,对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员; ..。

用gcc7.1;gcc5.2;clang3.8;gcc4.9;gcc4.8;gcc4.7在en.cppreference.com/w/cpp/language/decltype的代码片段中进行测试

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-16 09:18:35

严格按照标准,你似乎是对的,而且应该是double &&。我的推理链(来自C++17 (N4659)的所有引号):

8.2.5类成员访问expr.ref

1后缀表达式后面跟着点.或箭头->,可选地后面跟着关键字template (17.2),然后是id表达式,是后缀表达式。..。 2对于第一个选项(点),第一个表达式应为具有完整类类型的glvalue。 3缩写后缀表达式. is表达式为E1.E2E1称为对象表达式。..。E1.E2的类型和值类别确定如下。在其余的8.2.5中,cq表示constconst的缺失,vq表示volatilevolatile的缺失。cv表示6.9.3中定义的任意一组cv-限定符。 ..。 (4.2)如果E2是非静态数据成员,而E1的类型是“cq1 vq1 X”,而E2的类型是“cq2 vq2 T”,则表达式指定第一个表达式指定的对象的命名成员。如果E1是lvalue,那么E1.E2是lvalue;否则E1.E2是xvalue。..。

因此,如果.的左侧操作数是xvalue,则整个.表达式的结果也是如此。

8.2.3显式类型转换(函数表示法) expr.type.conv

1一个简单类型说明符(10.1.7.2)或类型名称说明符(17.6),后面跟着一个括号大小的可选表达式-列表,或者由一个带括号的-init-列表(初始化程序)构造指定类型的值。..。 2...表达式是指定类型的prvalue,其结果对象与初始化器直接初始化(11.6)。

因此,A()是一个prvalue。

最后:

8词组费用

10每当一个prvalue表达式显示为一个操作符的操作数时,就会应用临时物化转换(7.4)将该表达式转换为xvalue。

综合起来,这意味着A()是一个prvalue (来自8.2.3/2)。因为.要求它的LHS操作数是一个glvalue,所以临时物化转换是附加的( 8/10),结果是xvalue。因此,从8.2.5/(4.2)开始,因为E1是一个xvalue,所以E1.E2也是,在您的例子中是A().x

至于decltype

10.1.7.2简单类型说明符dcl.type.simple

4对于表达式e,由decltype(e)表示的类型定义如下: ..。 (4.3)如果e是xvalue,则decltype(e)T&&,其中Te的类型;

因为在您的例子中,(A().x)被确定为xvalue,所以它的dectlype应该是double &&

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50366460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档