Why in conditional operator (?:), second and third operands must have the same type?

故事扮演 提交于 2020-06-24 03:16:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!