Здравствуйте, remark, Вы писали:
R>Здравствуйте, tealex, Вы писали:
T>>О всевышний ! Ответь мне на вопрос !
T>> Counter (Counter const& x)
Посколько конструктор копирования принимает только неконстантную ссылку, то компилятор не может скопировать временную переменную, созданную в operator++() в возвращаемое значение. Поэтому msvc производит достаточно странную последовательность действий. Она вызывает у временного объекта operator float(), потом преобразует float в int, потом конструирует возвращаемое значение с помощью этого int'а.
Подозреваю, что такая последовательность преобразований является расширением msvc и не соотв. стандарту, т.к. содержит 2 пользовательских преобразования.
Если быть более точным, то msvc может связать временный объект и неконстантную ссылку. Просто видимо она считает это преобразование менее приоритетным. Сказать тут что-либо сложно, т.к. оба преобразования — расширения msvc. А эти расширения являются большей частью недокументированными.
Если это всё подытожить, то надо передавать копию в конструктор копирования как константную ссылку.
R>
Здравствуйте, tealex, Вы писали:
T>Здравствуйте, remark, Вы писали:
T>>> Counter (Counter const& x)
T>Ok )
T>действительно не ругается но причём здесь operator float () ???????
R> Поэтому msvc производит достаточно странную последовательность действий. Она вызывает у временного объекта operator float(), потом преобразует float в int, потом конструирует возвращаемое значение с помощью этого int'а.
T>>> Counter (Counter const& x)
R>Посколько конструктор копирования принимает только неконстантную ссылку, то компилятор не может скопировать временную переменную, созданную в operator++() в возвращаемое значение. Поэтому msvc производит достаточно странную последовательность действий. Она вызывает у временного объекта operator float(), потом преобразует float в int, потом конструирует возвращаемое значение с помощью этого int'а. R>Подозреваю, что такая последовательность преобразований является расширением msvc и не соотв. стандарту, т.к. содержит 2 пользовательских преобразования. R>Если быть более точным, то msvc может связать временный объект и неконстантную ссылку. Просто видимо она считает это преобразование менее приоритетным. Сказать тут что-либо сложно, т.к. оба преобразования — расширения msvc. А эти расширения являются большей частью недокументированными. R>Если это всё подытожить, то надо передавать копию в конструктор копирования как константную ссылку.
А на это же не ругается , хотя в принципе там то же вызывается копирующий конструктор
R>> Поэтому msvc производит достаточно странную последовательность действий. Она вызывает у временного объекта operator float(), потом преобразует float в int, потом конструирует возвращаемое значение с помощью этого int'а.
T>Это что дизасемблер ?
Да нет, просто отладчик студии с применением функции Step In (F11)
Ну или можно было отладочного вывода во все функции понапихать...
T>>>> Counter (Counter const& x)
R>>Посколько конструктор копирования принимает только неконстантную ссылку, то компилятор не может скопировать временную переменную, созданную в operator++() в возвращаемое значение. Поэтому msvc производит достаточно странную последовательность действий. Она вызывает у временного объекта operator float(), потом преобразует float в int, потом конструирует возвращаемое значение с помощью этого int'а. R>>Подозреваю, что такая последовательность преобразований является расширением msvc и не соотв. стандарту, т.к. содержит 2 пользовательских преобразования. R>>Если быть более точным, то msvc может связать временный объект и неконстантную ссылку. Просто видимо она считает это преобразование менее приоритетным. Сказать тут что-либо сложно, т.к. оба преобразования — расширения msvc. А эти расширения являются большей частью недокументированными. R>>Если это всё подытожить, то надо передавать копию в конструктор копирования как константную ссылку.
T>А на это же не ругается , хотя в принципе там то же вызывается копирующий конструктор T>
T>Counter a(1);
T>return a;
T>
T>в отличии от этого T>
T>return Counter (1);
T>
Тут не временный объект (r-value), а обычный объект (l-value). Неконстантные l-value без проблем связываются с неконстантными ссылками. r-value и константные и неконстантные *не* связываются с неконстантными ссылками. (хотя студия это умеет делать, но это уже отдельный вопрос)
Т.ч. разница есть. И, объявив конструктор копирования как Counter (Counter& x), ты как раз сказал коспилятору, что *хочешь* различать эту разницу. Если ты объявляешь как Counter (Counter const& x), то ты говоришь, что *не* хочешь различать эту разницу.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, tealex, Вы писали:
R>>> Поэтому msvc производит достаточно странную последовательность действий. Она вызывает у временного объекта operator float(), потом преобразует float в int, потом конструирует возвращаемое значение с помощью этого int'а.
T>>Это что дизасемблер ?
R>Да нет, просто отладчик студии с применением функции Step In (F11) R>Ну или можно было отладочного вывода во все функции понапихать...
Я понял .
Если я передаю временный обьект(по сылке) то функция принимающая должна принимать const (иначе не произойдёт связование)
Если не временный обьект то функция принимающая может быть как const так и не const
типа того ) ?
ну на саом деле ситуция не тривиальная )
если бы не operator float то я бы просто пропустил
Здравствуйте, tealex, Вы писали:
T>Я понял . T>Если я передаю временный обьект(по сылке) то функция принимающая должна принимать const (иначе не произойдёт связование) T>Если не временный обьект то функция принимающая может быть как const так и не const
T>типа того ) ?
Именно.
Либо можно принимать по значению, если объект "лёгкий".
Здравствуйте, tealex, Вы писали:
T>Ну ещё вопросы:
T>почему в этом случае вызывается конструктор копирования
T>
T> Counter a(77);
T> return a;
T>
T>а в этом нет T>
T>return Counter (77);
T>
T> опять не тривиально для меня )))
Это implementation defined поведение. Конструктор копирования может вызываться и во втором случае.
Т.е. просто студия посчитала, что во втором случае элиминировать копирование легче и сделала это.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, tealex, Вы писали:
T>>Ну ещё вопросы:
T>>почему в этом случае вызывается конструктор копирования
T>>
T>> Counter a(77);
T>> return a;
T>>
T>>а в этом нет T>>
T>>return Counter (77);
T>>
T>> опять не тривиально для меня )))
R>Это implementation defined поведение. Конструктор копирования может вызываться и во втором случае. R>Т.е. просто студия посчитала, что во втором случае элиминировать копирование легче и сделала это.