Почему конструктор копирования вызывается вместо конструктора преобразования?
Итак, в основном этот код:
class A {
};
class B {
B (const B& b) {}
public:
B (){}
B (const A& a) {}
};
int main()
{
A a;
B b1(a); //OK
B b2 = a; //Error
}
только генерирует ошибку для B b2 = a
, И эта ошибка
ошибка: 'B::B(const B&)' является частной
Почему он пытается вызвать конструктор копирования в дополнение к конструктору прямого преобразования?
Из сообщения об ошибке ясно, что временный B
создается, который затем используется для копирования конструкции, но почему? Где это в стандарте?
1 ответ
B b2 = a;
Это называется копией инициализации.
Это делает следующее:
- Создать объект типа
B
отa
используяB (const A& a)
, - Скопируйте созданный временный объект в
b2
используяB (const B& b)
, - Уничтожьте временный объект, используя
~B()
,
Вы получаете ошибку не на шаге 1, а на шаге 2.
Где это в стандарте?
C++ 03 8.5 Инициализаторы
Параграф 14:
....
- Если тип назначения является (возможно, cv-квалифицированным) типом класса:
...
...
- В противном случае (т. Е. Для остальных случаев инициализации копирования) определяемые пользователем последовательности преобразования, которые могут преобразовываться из типа источника в тип назначения или (когда используется функция преобразования) в производный класс, перечисляются, как описано в 13.3..1.4, а лучший выбирается с помощью разрешения перегрузки (13.3). Если преобразование не может быть выполнено или является неоднозначным, инициализация неверна. Выбранная функция вызывается с выражением инициализатора в качестве аргумента; если функция является конструктором, вызов инициализирует временный объект целевого типа. Результат вызова (который является временным для случая конструктора) затем используется для прямой инициализации, в соответствии с приведенными выше правилами, объекта, который является местом назначения инициализации копирования. В некоторых случаях реализация позволяет исключить копирование, присущее этой прямой инициализации, путем создания промежуточного результата непосредственно в инициализируемом объекте; см. 12.2, 12.8.