Почему в условном операторе (?:), второй и третий операнды должны иметь одинаковый тип?
почему условный оператор(?:
), второй и третий операнды должны иметь один и тот же тип?
мой код такой:
#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, строка не допускается.