Неявное преобразование второго порядка

Рассмотрим следующий код:

#include <iostream>

class first
{
public:
constexpr first(bool val) noexcept : _value{val} {}
constexpr operator bool() const noexcept {return _value;}
private:
bool _value;
};

class second
{
public:
constexpr second(first val) noexcept : _value{val} {}
constexpr operator first() const noexcept {return _value;}
private:
first _value;
};

int main(int argc, char** argv)
{
first f{false};
second s{true};
bool b1 = f;
bool b2 = s; // Not compiling
return 0;
}

До недавнего времени я думал, что стандарт и компиляторы достаточно «умны», чтобы найти требуемую последовательность преобразования, когда она существует.

Другими словами, я думал, что bool b2 = s будет конвертировать s в firstи затем bool, Но, видимо, этого не происходит.

Каков правильный подход для получения эквивалентного поведения для first а также second?

1

Решение

Это невозможно, потому что разрешено только одно пользовательское преобразование:

4 Стандартные преобразования [конв]

7 [Примечание: для типов классов пользовательские преобразования рассматриваются как
Что ж; см. 12.3. Как правило, неявная последовательность преобразования (13.3.3.1)
состоит из стандартной последовательности преобразования, за которой следует определенный пользователем
преобразование, сопровождаемое другой стандартной последовательностью преобразования. — конец
нота ]

так же как

12.3 Преобразования [class.conv]

4 Не более одного пользовательского преобразования (конструктор или функция преобразования) неявно применяется к одному
значение.

См. Также пункты 5 (С осторожностью относитесь к пользовательским функциям преобразования), 28 (умные указатели) и 30 (прокси-классы) из более эффективного C ++.

Для стандартных преобразований (с использованием встроенных типов) нет ограничений на количество преобразований в последовательности.

3

Другие решения

Вам нужно будет добавить operator bool в second, Компилятор будет смотреть только на одно пользовательское неявное преобразование.

1

По вопросам рекламы ammmcru@yandex.ru