从移位运算符,位运算符和sizeof运算符产生的结果的值类别是什么? [英] What is the value category of result yielded from shift operators, bit-wise operators, and sizeof operator?
问题描述
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屋!