Несколько неявных преобразований для пользовательских типов не допускается?

class C {
public:
    C() { }
};

class B {
public:
    B(C c) { }
    B() { }
};

class A {
public:
    A(bool b) { }
    A(B b) { }
};

int main() {
    A a1 = true; // bool -> A        is allowed
    A a2 = B();  // B -> A           is allowed

    A a3 = 7;    // int -> bool -> A is allowed
    A a4 = C();  // C -> B -> A      isn't allowed
}

Почему я могу использовать двухступенчатое неявное преобразование сbool но может'не использовать его сC? Каково общее правило, описывающее многошаговое неявное преобразование?

Ответы на вопрос(2)

Решение Вопроса

Там нет многошаговойопределяемые пользователем неявное преобразование.

int -> bool -> A

разрешено, потому чтоint->bool преобразование нет определяется пользователем.

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

1 Преобразования типов объектов класса могут быть определены конструкторами и функциями преобразования. Эти преобразования называются пользовательскими преобразованиями и используются для неявных преобразований типов (пункт 4), для инициализации (8.5) и для явных преобразований типов (5.4, 5.2.9).

2 Пользовательские преобразования применяются только в том случае, если они однозначны (10.2, 12.3.2). Преобразования подчиняются правилам контроля доступа (пункт 11). Контроль доступа применяется после разрешения неоднозначности (3.4).

3 [Примечание: см. 13.3 для обсуждения использования преобразований в вызовах функций, а также примеров ниже. -конечная нота]

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

 Luchian Grigore11 окт. 2012 г., 21:53
@Lescott есть много встроенных конверсий / рекламных акций.int->bool это то, что у вас есть в данном конкретном случае.
 Jofsey11 окт. 2012 г., 21:52
Итак, нет других базовых преобразований, кроме?int->bool

Так как эта конструкция совершенно законна

A a4((C()));

Проблема в том, что вы используете инициацию копирования. Действительно, ваш пример равен

A a4((A(C()));

8.5 / 16

Семантика инициализаторов следующая. Тип назначения - это тип инициализируемого объекта или ссылки, а тип источника - тип выражения инициализатора. Если инициализатор не является одним (возможно, заключенным в скобки) выражением, тип источника не определен.

Если тип назначения является (возможно, cv-квалифицированным) типом класса: -

 В противном случае (т. Е. Для оставшихся случаев инициализации копирования) пользовательские последовательности преобразования, которые могут преобразовывать из исходного типа в тип назначения или (когда используется функция преобразования) в его производный класс, перечисляются, как описано в 13.3. 1.4, а лучший выбирается через разрешение перегрузки (13.3).

13.3.1.4/1

При условиях, указанных в 8.5, как часть инициализации копирования объекта типа класса, может быть вызвано пользовательское преобразование для преобразования выражения инициализатора в тип инициализируемого объекта.

Разрешение перегрузки используется для выбора определяемого пользователем преобразования, которое будет вызвано. При условии, что "cv1 T ” является типом инициализируемого объекта, с T типом класса, функции-кандидаты выбираются следующим образом: Конвертирующие конструкторы (12.3.1) из T являются функциями-кандидатами.

 Когда тип выражения инициализатора является типом класса «резюме S ”рассматриваются неявные функции преобразования S и его базовых классов.

13.3.3.1/4

Однако при рассмотрении аргумента конструктора или пользовательской функции преобразования, которая является кандидатом на 13.3.1.3 при вызове для копирования / перемещения временного объекта на втором шаге инициализации копирования класса, на 13.3.1.7 при передаче список инициализатора в качестве единственного аргумента или когда список инициализатора имеет ровно один элемент, и преобразование в некоторый класс X или ссылку на (возможно, cv-квалифицированную) X рассматривается для первого параметра конструктора X, или13.3.1.413.3.1.5 или 13.3.1.6 во всех случаях,рассматриваются только стандартные последовательности преобразования и последовательности преобразования эллипса.

Ваше пользовательское преобразование (C -> Б) не рассматривается в этом случае.

Ваш ответ на вопрос