Incompatible operand types ('const std::nullopt_t' and 'long')

Всем привет

Есть следующий код:

optional<ssize_t> Socket::ReadWithoutHangCheck(void *buffer, size_t size) {
    auto result = read(_socketFileDescriptor, buffer, size);
    return result == -1 ? nullopt : result;
}

Почему если не привести nullopt явно к optional<ssize_t>, то есть, к примеру, сделать так:

return result == -1 ? static_cast<optional<ssize_t>>(nullopt) : result;

То выскакивает ошибка Incompatible operand types ('const std::nullopt_t' and 'long')?

Я понимаю, что означает эта ошибка, но не понимаю, почему там в принципе происходит несоответствие типов. Разве тернарный оператор не будет здесь обозначать что-то типа:

if (result == -1) 
    return nullopt 
else 
    return result;

К слову, так ошибки нет в несоответствии типов.


Ответы (1 шт):

Автор решения: Maxim Timakov

Блок if-else и оператор ?: - разные вещи.

У тренарного оператора результаты должны приводится к общему типу. (см. std::common_type)

то есть код

return cause ? A : B;

преобразуется к виду

using common_type = std::common_type_t<decltype(A), decltype(B)>
return cause ? common_type{A} : common_type{B};

В данном случае такого общего типа не найдено.

скорее всего у optional не найден подходящий конструктор неявного преобразования

→ Ссылка