C++ неявное приведение типов

292
14 ноября 2018, 09:40

подскажите пожалуйста, как в компилятор С++ разрешает проблему неявного привидения типов. В частности интересует вопрос: почему в первом случае компилятор сможет построить цепочку преобразований, а во втором нет? Или подскажите где можно об этом почитать.

1

struct String 
{
    operator int();
};
int main()
{
    String s("Hello");
    if (s) {}
}

2

struct String
{
    operator String2();
};
struct String2
{
    operator bool();
};
int main()
{
    String s("Hello");
    if (s) {}
}
Answer 1

В стандарте C++ описаны несколько последовательностей неявного конвертирования, которые могут случаться в программах ([over.best.ics]). Ваш случай описан в [over.ics.user], в котором говорится, что определённая пользователем функция конвертирования, может использоваться лишь один раз во всей последовательности. Т.е. последовательность, которая содержит использование переопределённого оператора преобразования, может содержать не более двух стандартных преобразований и лишь одно преобразование определённое пользователем.

Ваш первый случай:

  1. Конвертировать s в int - определённое пользователем преобразование.
  2. Конвертировать int в bool — стандартное преобразование.

Т.е. всё нормально, не более одного пользовательского преобразования и не более 2-х стандартных преобразований.

Ваш второй случай (гипотетически):

  1. Конвертировать s в String2 - определённое пользователем преобразование.
  2. Конвертировать String2 в bool - определённое пользователем преобразование.

В данной цепочке получаются 2 пользовательских преобразования, что запрещено стандартом.

P.S. в обоих случаях есть ещё стандартное преобразование (identity), которое идёт первым. Но это роли не играет.

Answer 2

Если я вас правильно понял, вы хотите узнать почему в if String не привелся к String2, который может приводится к bool? Если так, то: компилятор не может знать, что вы хотите (чтобы String привелся к String2), для этого нужно явно это указать. К примеру у вас может быть оператор приведения к String3, который тоже приводится к bool - какой тогда компилятору выбирать? Почему работает первый вариант: потому что в if явно требуется преобразование к bool (который является по сути числовым типом, как, например int).

READ ALSO
Что из себя представляет null?

Что из себя представляет null?

Нет такого типа, которому бы соответствовал instanceof от null

144
Используя Regex удалить всё, кроме того, что подходит под паттерн

Используя Regex удалить всё, кроме того, что подходит под паттерн

Собственно вопрос в том, как реализовать код который из string будет выбирать только ту часть, что удовлетворяет условиям, а всё остальное удалятьВ...

136
Почему isInterrupted() не меняет свое значение?

Почему isInterrupted() не меняет свое значение?

Решил проверить срабатывание isInterrupted() следующим кодом:

157
freemarker ошибка на странице

freemarker ошибка на странице

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

186