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

时间:2012-03-12 04:57:48

标签: 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;
}

使用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’

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

(1)在我看来,如果(a>b)为真,则表达式( a>b ? "a is greater\n" : b )将返回"a is greater\n",而cout << "a is greater\n"将输出字符串;
否则表达式将返回bcout << b将输出b的值。

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

(2)第二个表达式会出现同样的错误。

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

5 个答案:

答案 0 :(得分:30)

你应该尝试分解正在发生的事情来理解:

cout << ( a>b ? "a is greater\n" : b );

这转换为:

operator<<(cout, ( a>b ? "a is greater\n" : b ));

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

ostream& operator<<(ostream&, int);
ostream& operator<<(ostream&, const char*);

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

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

 auto c = a>b ? "test" : 0;

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

编辑:

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

if (a)
    b;
else
    c;

虽然实际上是这样的:

if (a)
    return b;
else
    return c;

答案 1 :(得分:5)

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

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

这源于这样一个事实:C ++是一种静态类型语言,其中所有类型都必须在编译时知道。

答案 2 :(得分:4)

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

虽然必须隐式转换为相同的类型。原因很简单:运算符必须产生一个值,编译器必须能够计算出该值的类型。如果两种类型之间没有隐式转换,则表达式没有一种类型可以生成。

答案 3 :(得分:2)

它是一种强类型语言,它需要将整体?:作为变量或语句,如:

int i = 3;
int j = 5;
int k = (2 > 1 ? i : j) + 3;

在这种情况下,如果我是一个字符串,你会期望它应该为你做什么?

答案 4 :(得分:2)

?:表达式将生成一个值(称为 rvalue ),该值将被分配给变量(称为 lvalue ),如J.N.提到,C ++是一种静态类型语言, lvalue 必须在编译时才知道。

int num = a>b ? a : "eh, string?";

上面的代码不会编译,导致变量num只能包含 int ,不允许使用字符串。