Когда вы пишете
Complex a = 2;
, компилятор не будет напрямую вызывать конструктор Complex
, используя 0 в качестве аргумента по умолчанию для построения a
, но вместо этого он будет учитывать, сможет ли он "преобразовать" 2 вComplex
.
Чтобы выполнить преобразование, он найдет вашу Complex(re,im)
версию и сможет использовать ее благодаря значению по умолчанию и тому факту, что вы не объявили свой конструктор explicit
, но тогда он будетнужно найти способ передачи этого значения в a
.
Инструментом для этого «переноса» может быть конструктор копирования.Однако комплексное значение, которое может быть построено с помощью Complex(re,im)
, является временным , и по некоторым сомнительным причинам в C ++ вам не разрешено передавать временное значение как неконстантную ссылку на функцию.
Таким образом, ваш конструктор копирования не может использоваться с временным, и компилятор застрял, так как нет способов инициализировать a
, используя 2.
Если вы объявляете ваш конструктор копирования вместо принятия ссылки const
затем временная переменная может быть передана в ваш конструктор копирования для инициализации a
, и все будет работать так, как вы ожидаете.
Непосредственная инициализация a
могла бы быть выполнена с использованием синтаксиса Complex a(2)
, который в данном случае нене нужно использовать конструктор копирования.
Обратите внимание, что, как ни странно, может быть, когда вы используете синтаксис Complex a = ...
, компилятор должен проверить, допустимо ли использовать конструктор копирования, но как только эта законность была достигнутапроверил, что разрешено не вызывать его и использовать вместо него прямую инициализацию.Другими словами, даже если вам нужно объявить, что ваш конструктор копирования принимает ссылку на const для возможности компиляции, компилятор может фактически пропустить эту часть и напрямую собрать a
без вызова конструктора копирования (даже если конструктор копирования - как в вашемслучай - имеет побочные эффекты).Это явно сумасшедшее правило было добавлено, чтобы позволить некоторую оптимизацию в сгенерированном коде.