为什么在条件运算符(?:
)中,第二个和第三个操作数必须具有相同的类型?
我的代码是这样的:
#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"
将输出字符串;
否则表达式将返回b
,cout << b
将输出b的值。
但不幸的是,它不是这样的。为什么?
(2)第二个表达式会出现同样的错误。
PS:我知道,标准是谁必须这样,但是,为什么标准会这样说呢?
答案 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 ,不允许使用字符串。