Подтвердить что ты не робот

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

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

Мой код:

#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: Я знаю, это стандарт, который говорит, что это должно быть так, но почему стандарт так говорит?

4b9b3361

Ответ 1

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

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

EDIT:

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

if (a)
    b;
else
    c;

Пока это на самом деле:

if (a)
    return b;
else
    return c;

Ответ 2

Я блуждаю, почему они должны иметь один и тот же тип?

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

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

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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