Почему в условном операторе (?:), второй и третий операнды должны иметь одинаковый тип?

почему условный оператор(?:), второй и третий операнды должны иметь один и тот же тип?

мой код такой:

#include <iostream>
using std::cout;

int main()
{
    int a=2, b=3;
    cout << ( a>b ? "a is greatern" : b );  /* expression ONE */
    a>b? "a is greatern" : 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 greatern" : b )вернутся "a is greatern" и cout << "a is greatern" выведет эту строку;
в противном случае выражение вернется b и cout << b выведет значение b.

но, к сожалению, это не так. Почему?

(2) второе выражение получает ту же ошибку.

PS: Я знаю, это стандарт, который говорит, что это должно быть так, но почему стандарт так говорит?

5 ответов


вы должны попробовать разложить то, что происходит, чтобы понять:

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++ - это статически типизированный язык. Все типы должны быть известны во время компиляции.

EDIT:

вы думаете о a ? b : c следующим образом:

if (a)
    b;
else
    c;

хотя на самом деле это:

if (a)
    return b;
else
    return c;

они на самом деле не должны быть одного типа. Например, выражение типа:int a = argc > 1 ? 2 : 'a'; вполне допустимо, хотя 2 типа int и 'a' типа char.

однако должно быть неявное преобразование в тот же тип. Причина проста: оператор должен уступить один value, и компилятор должен иметь возможность определить тип этого значения. Если между этими двумя типами нет неявного преобразования, нет один тип для создания выражения.


интересно, почему они должны иметь один и тот же тип?

в C++ любое выражение должно иметь один тип, и компилятор должен иметь возможность вывести его во время компиляции.

Это связано с тем, что c++ - язык со статической типизацией, в котором все типы должны быть известны во время компиляции.


это сильный язык типов, и он должен обрабатывать все ?: как переменная или оператор, например:

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

в таком случае, что вы ожидаете, что он должен сделать для вас, если я строка?


на ?: выражение выдаст значение (называемое правосторонним значением), который должен быть назначен переменной (которая называется lvalue), как J. N. metioned, C++ является статически типизированным языком,lvalue должно быть известно во время компиляции.

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

код выше не будет компилироваться, вызовите переменную num может содержать только int, строка не допускается.