三元运算符为什么以及何时返回左值?

Sou*_*mar 39 c++ rvalue conditional-operator lvalue

很长一段时间以来,我认为三元运算符总是返回一个右值.但令我惊讶的是,事实并非如此.在下面的代码中,我没有看到返回值foo和三元运算符的返回值之间的区别.

#include <iostream>
int g = 20 ;

int foo()
{
    return g ;
}

int main()
{
    int i= 2,j =10 ;

    foo()=10 ; // not Ok 
    ((i < 3) ? i : j) = 7; //Ok
    std::cout << i <<","<<j << "," <<g << std::endl ;
}
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 35

这两个ijglvalues(见这个值类参考了解详细信息).

然后,如果您阅读此条件运算符引用,我们就会到达这一点:

4)如果E2和E3是相同类型和相同值类别的glvalues,则结果具有相同的类型和值类别

因此结果(i < 3) ? i : j是glvalue,可以分配给.

但是做这样的事情真的不是我推荐的.

  • @Someprogrammerdude - 你的第一个评论代表了左值概念的起源:可以在作业左侧的东西.虽然这个概念超越了这个概念,但这个名字仍然存在. (3认同)
  • @SoulimaneMammar - 哪个编译器?gnu c ++对"Hello"的诊断="World"`是`错误:只读位置的分配'"Hello"'`,而LLVM是`错误:只读变量不可赋值`. (3认同)
  • @SoulimaneMammar问题在于constness,而不是value类别.你不能在赋值的左侧放置一个删除了`operator =`的对象; 这不会使它不是左值. (2认同)
  • @SoulimaneMammar数组(例如字符串文字)是棘手的左值.当使用它们的值时,它们会隐式转换为指向第一个元素的指针(这称为衰减),而衰减指针则不是*不是左值.这就是错误诊断的原因.但更一般地说,即使数组不是const,数组也不能在语言中赋值. (2认同)
  • @SoulimaneMammar 文字字符串是`const char` 数组。它们衰减为指向数组第一个元素的 *constant* 指针(常量指针,因为文字字符串的位置也不能更改)。这个指针的类型是`const char * const`。由于指针是常量,你不能改变它,这意味着不能把它放在赋值的左侧。 (2认同)
  • 这个的主要用例是引用的初始化:`int&i = b?i1:i2;` (2认同)

Sto*_*ica 20

有关这方面的规则详见[expr.cond].对于几种类型和值类别的组合,有许多分支.但最终,表达式是默认情况下的prvalue.第5段涵盖了您的示例中的案例:

如果第二个和第三个操作数是相同值类别的glvalues并且具有相同的类型,则结果是该类型和值类别,如果第二个或第三个操作数是位字段,则它是位字段,或者如果两者都是位字段.

无论ij,是变量的名称,是类型的左值表达式int.因此条件运算符产生int左值.