Многие начинающие программисты предполагают, что троичный оператор ?:
является всего лишь кратким условным оператором if, что верно во многих случаях (с точки зрения начинающих разработчиков).Но есть ограничения, и они совсем не одно и то же ..
Оцененный результат троичного оператора должен быть таким же Тип (или конвертируемым в один или другой)независимо от того, является ли проверенное утверждение истинным или ложным.
#include <string>
int
main (int argc, char *argv)
{
std::string s;
0 == 0 ? s = "123": 123;
}
В этом автономном примере (который не компилируется, чтобы легко доказать мою точку зрения) мы получаем следующую ошибку:
foo.cpp: In function 'int main(int, char**)':
foo.cpp:7:23: error: no match for ternary 'operator?:' in 'true ? s.std::basic_string<_CharT, _Traits, _Alloc>::operator=<char, std::char_traits<char>, std::allocator<char> >(((const char*)"123")) : 123'
Это потому, что выражение будет равно std::string&
, если утверждение истинно, и int
, если оно ложно.Два разных типа, в зависимости от того, какое выражение является истинным или нет? Не разрешено.
Поэтому компилятор пытается неявно преобразовать любую из сторон, чтобы найти совпадение, но не смог найти подходящего преобразования, и мы получили ошибку.
int
main (int argc, char *argv[])
{
0 == 0 ? "123": 123;
}
Приведенный выше фрагмент кода вызовет гораздо более приятную ошибку компиляции, чем мы имели ранее (при попытке компиляции он будет g++
).И как указано в этом посте;оба результата операндов ?:
должны быть одного типа.
foo.cpp: In function 'int main(int, char**)':
foo.cpp:4:19: error: operands to ?: have different types 'const char*' and 'int'