Почему конструктор копирования вызывается вместо конструктора преобразования?

Итак, в основном этот код:

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;

Это называется копией инициализации.

Это делает следующее:

  1. Создать объект типа B от a используя B (const A& a),
  2. Скопируйте созданный временный объект в b2 используя B (const B& b),
  3. Уничтожьте временный объект, используя ~B(),

Вы получаете ошибку не на шаге 1, а на шаге 2.

Где это в стандарте?

C++ 03 8.5 Инициализаторы
Параграф 14:

....
- Если тип назначения является (возможно, cv-квалифицированным) типом класса:
...
...
- В противном случае (т. Е. Для остальных случаев инициализации копирования) определяемые пользователем последовательности преобразования, которые могут преобразовываться из типа источника в тип назначения или (когда используется функция преобразования) в производный класс, перечисляются, как описано в 13.3..1.4, а лучший выбирается с помощью разрешения перегрузки (13.3). Если преобразование не может быть выполнено или является неоднозначным, инициализация неверна. Выбранная функция вызывается с выражением инициализатора в качестве аргумента; если функция является конструктором, вызов инициализирует временный объект целевого типа. Результат вызова (который является временным для случая конструктора) затем используется для прямой инициализации, в соответствии с приведенными выше правилами, объекта, который является местом назначения инициализации копирования. В некоторых случаях реализация позволяет исключить копирование, присущее этой прямой инициализации, путем создания промежуточного результата непосредственно в инициализируемом объекте; см. 12.2, 12.8.

Другие вопросы по тегам