为什么在条件运算符(?:)中,第二个和第三个操作数必须具有相同的类型?

Yis*_*ang 16 c c++ operator-keyword

为什么在条件运算符(?:),第二和第三个操作数必须具有相同的类型?

我的代码是这样的:

#include <iostream>
using std::cout;

int main()
{
    int a=2, b=3;
    cout << ( a>b ? "a is greater\n" : b );  /* expression ONE */
    a>b? "a is greater\n" : b;               /* expression TWO */

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用g ++编译时,会发出错误:

main.cpp:7:36: error: operands to ?: have different types ‘const char*’ and ‘int’
main.cpp:8:28: error: operands to ?: have different types ‘const char*’ and ‘int’
Run Code Online (Sandbox Code Playgroud)

我想知道为什么他们必须有相同的类型?

(1)在我看来,如果(a>b)是,那么表达式( a>b ? "a is greater\n" : b )将返回"a is greater\n"cout << "a is greater\n"输出该字符串;
否则表达式将返回b,cout << b并将输出b的值.

但是,不幸的是它不是这样的.为什么?

(2)第二个表达式得到相同的错误.

PS:我知道,标准是谁必须这样,但是,为什么标准这样说呢?

J.N*_*.N. 30

您应该尝试分解正在发生的事情以便理解:

cout << ( a>b ? "a is greater\n" : b );
Run Code Online (Sandbox Code Playgroud)

这意味着:

operator<<(cout, ( a>b ? "a is greater\n" : b ));
Run Code Online (Sandbox Code Playgroud)

在该阶段,编译器必须选择以下重载之一:

ostream& operator<<(ostream&, int);
ostream& operator<<(ostream&, const char*);
Run Code Online (Sandbox Code Playgroud)

但它不能,因为三元运算符的结果类型尚不知道(仅在运行时).

为了让事情更清楚,请考虑这样:

 auto c = a>b ? "test" : 0;
Run Code Online (Sandbox Code Playgroud)

会是什么类型的c?它无法在编译时决定.C++是一种静态类型语言.所有类型必须在编译时知道.

编辑:

您正在考虑a ? b : c以下方式:

if (a)
    b;
else
    c;
Run Code Online (Sandbox Code Playgroud)

虽然它实际上是这样的:

if (a)
    return b;
else
    return c;
Run Code Online (Sandbox Code Playgroud)

  • @UniMouS你没有分配给其他人,但你可以.三元运算符定义为返回值.你只是忽略它,但它就在那里. (3认同)
  • @UniMouS,如果你把它写成`a&gt;b,你的第二个表达式会起作用吗?(void)"a is Greater\n" : (void)b;` 那就是告诉编译器丢弃子表达式的值。 (2认同)

Alo*_*ave 5

我想知道为什么他们必须有相同的类型?

在C++中,任何表达式都必须具有单一类型,编译器应该能够在编译时推导出它.

这源于C++是一种静态类型语言,其中所有类型必须在编译时才知道.


Jer*_*fin 5

它们实际上不必是同一类型。例如,像这样的表达式int a = argc > 1 ? 2 : 'a';是完全允许的,即使2是 type int,并且'a'是 typechar

但是,确实必须隐式转换为相同的类型。原因很简单:运算符必须产生一个值,而编译器必须能够确定该值的类型。如果两种类型之间没有隐式转换,则表达式不会生成一种类型。