从移位运算符,位运算符和sizeof运算符产生的结果的值类别是什么? [英] What is the value category of result yielded from shift operators, bit-wise operators, and sizeof operator?

查看:144
本文介绍了从移位运算符,位运算符和sizeof运算符产生的结果的值类别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Shift操作符:< >>
位运算符: code>〜
& ^ |
sizeof运算符: sizeof()

Shift operators: << >> bit-wise operators: ~, &, ^, | sizeof operator: sizeof()

标准(n3797),我只能确认产生prvalue(5.3.1 / 2),但不是上面的其他。

Per the C++ standard (n3797), I can only confirm that ~ yields prvalue (5.3.1/2), but not the others above.

推荐答案

至于我可以告诉结果是 prvalues ,但这只是一个投机。这似乎在类似于中所涵盖的操作数的值类别中的指定方式。未指定时使用C ++运算符?在应用间接时,标准是否要求指针变量的左值到值的转换? / a>。

As far as I can tell the results are prvalues but that is just a speculative. This seems to be under-specified in a similar way to the value categories of operands which is covered in What is the value category of the operands of C++ operators when unspecified? and Does the standard mandate an lvalue-to-rvalue conversion of the pointer variable when applying indirection?.

我们可以从 3.10 部分看到Lvalues和Rvalues下面的注释:

We can see from section 3.10 Lvalues and rvalues has the following note:


第5节中每个内置操作符的讨论表明它产生的值的
类别,

但我们可以看到 code>仅在少数情况下明确说明了值类别。在这个特定问题的情况下,仅仅明确地说明& 〜的结果的值类别 code>。

but as we can see section 5 only spells out the value category explicitly in a few cases. In the case of this particular question only spells out explicitly the value category of the result for & and ~.

即使不足,我们可以找到指向一致方向的线索。我们可以提出一个参数,说明>> << ^ | 转换为 prvalues 。这不会决定结果的值类别,但它似乎排除了结果 xvalue 根据 5 段落 7 其中包含以下注释:

Even though it is underspecified we can find clues that point us in a consistent direction. We can make an argument that the operands for >>, <<, ^ and | are converted to prvalues. This does not dictate the value category of the result but it does seem to exclude the result being an xvalue as per section 5 paragraph 7 which has the following note:


如果是xvalue,表达式是:

An expression is an xvalue if it is:

- 调用
函数的结果,无论是隐式还是显式,返回类型是对象类型的
值,

— the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,

- 转换为
对象类型的右值引用,

— a cast to an rvalue reference to object type,

- 类成员访问表达式指定
非静态数据成员非引用类型,其中对象
表达式是xvalue,或

— a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or

- a $ *
中的指向成员表达式第一个操作数是xvalue,第二个操作数是一个
指向数据成员的指针。

— a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.

一般来说,这个规则的效果是
命名的右值引用被视为左值,未命名的右值
引用对象被视为xvalues;

In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether named or not.

我没有看到任何合理的论据,结果可能是一个左值,所以基本上留给我们一个 prvalue

I don't see any reasonable argument that the result could be an lvalue so that basically leaves us with a prvalue.

因此细节如下:

& 5.3.1 一元运算符 2

每个下列一元运算符的结果是一个prvalue。

The result of each of the following unary operators is a prvalue.

5.8 段落 部分中说明的部分中包含的整体促销:

The shift operators require the integral promotions which is covered in section 5.8 Shift operators paragraph 1 which says:


操作数应为整数或无范围的枚举类型,并执行整数提升。

The operands shall be of integral or unscoped enumeration type and integral promotions are performed.

,我们可以看到积分促销活动需要 4.5 整体促销部分中的 prvalues 开头为:

and we can see that the integral promotions require prvalues from section 4.5 Integral promotions which says in every paragraph starts with:


一个价值[...]

A prvalue of [...]

^ | 需要通常的算术转换说:

Both ^ and | require the usual arithmetic conversions and both say:


运算符仅适用于整数或无范围的枚举操作数

operator applies only to integral or unscoped enumeration operands


b $ b

,因此常用算术转换的最后一句适用于:


,将对两个操作数执行积分促销(4.5)。 59

Luc Danton在回答经验确定C ++ 11表达式的值类别?。该方法使用以下代码:

Luc Danton has an empirical approach to determining the value category of an expression in his answer to Empirically determine value category of C++11 expression?. The approach uses the following code:

template<typename T>
struct value_category {
    // Or can be an integral or enum value
    static constexpr auto value = "prvalue";
};

template<typename T>
struct value_category<T&> {
    static constexpr auto value = "lvalue";
};

template<typename T>
struct value_category<T&&> {
    static constexpr auto value = "xvalue";
};

// Double parens for ensuring we inspect an expression,
// not an entity
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value

,答案概述逻辑如下:


一个左值表达式导致一个左值引用类型,
中的x值,右值引用类型,以及只是类型中的prvalue。

an lvalue expression results in an lvalue reference type, an xvalue in an rvalue reference type, and a prvalue in just the type.

以下示例都会生成 prvalue see it live

int x = 10, y = 2 ;
int &xr = x ;
int &yr = y ;

std::cout << VALUE_CATEGORY( x << y ) << std::endl ;
std::cout << VALUE_CATEGORY( 10 << 2 ) << std::endl ;
std::cout << VALUE_CATEGORY( xr << yr ) << std::endl ;

std::cout << VALUE_CATEGORY( x | y ) << std::endl ;
std::cout << VALUE_CATEGORY( 10 | 2 ) << std::endl ;

std::cout << VALUE_CATEGORY( x ^ y ) << std::endl ;
std::cout << VALUE_CATEGORY( 10 ^ 2 ) << std::endl ;

std::cout << VALUE_CATEGORY( sizeof( int ) ) << std::endl ;
std::cout << VALUE_CATEGORY( sizeof( x ) ) << std::endl ;

这篇关于从移位运算符,位运算符和sizeof运算符产生的结果的值类别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆