问题
Why in conditional operator(?:
), second and third operands must have the same type?
My code like this:
#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;
}
When compile it using g++, it issue an error:
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’
I wonder why they must have the same type?
(1) In my opinion, if (a>b)
is true, then the expression ( a>b ? "a is greater\n" : b )
will return "a is greater\n"
and cout << "a is greater\n"
will output that string;
otherwise the expression will return b
, and cout << b
will output the value of b.
But, unfortunately it is not like this. WHY?
(2) The second expression gets the same error.
PS: I know, it is the standard who says it must be like this, but, why the standard say so?
回答1:
You should try to decompose what's happening to understand:
cout << ( a>b ? "a is greater\n" : b );
This translates to :
operator<<(cout, ( a>b ? "a is greater\n" : b ));
At that stage the compiler must choose one of the following overloads:
ostream& operator<<(ostream&, int);
ostream& operator<<(ostream&, const char*);
But it can't because the type of result of the ternary operator is not known yet (only at runtime).
To make things clearer think like this:
auto c = a>b ? "test" : 0;
What would be the type of c
? It can't be decided at compile time. C++ is a statically typed language. All types must be known at compile time.
EDIT:
You are thinking of a ? b : c
in the following way:
if (a)
b;
else
c;
While it is actually this:
if (a)
return b;
else
return c;
回答2:
I wonder why they must have the same type?
In C++ any expression must have a single type, and the compiler should be able to deduce it at compile time.
This stems from the fact that C++ is a statically typed language wherein all types must be known at compile time.
回答3:
They don't really have to be the same type. For example, an expression like: int a = argc > 1 ? 2 : 'a';
is entirely permissible, even though 2
is of type int
, and 'a'
is of type char
.
There does have to be an implicit conversion to the same type though. The reason is simple: the operator has to yield one value, and the compiler has to be able to figure out the type of that value. If there's no implicit conversion between the two types, there's no one type for the expression to produce.
回答4:
It's a strong type language and it need to treat the whole ?: as a variable or statement, like:
int i = 3;
int j = 5;
int k = (2 > 1 ? i : j) + 3;
in such a case, what would you expect it should do for you if i is a string?
回答5:
the ?:
expression will produce a value(called rvalue), which is to be assigned to a variable(which is called lvalue), as J.N. metioned, C++ is a statically typed language, lvalue must be known at compile time.
int num = a>b ? a : "eh, string?";
The code above won't compile, cause the variable num
can only hold an int, string is not allowed.
来源:https://stackoverflow.com/questions/9661952/why-in-conditional-operator-second-and-third-operands-must-have-the-same-t