Re[6]: Конструктор копирования из шаблонного типа
От: ilvi Россия  
Дата: 18.08.09 02:00
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>
struct A
ЮЖ>{
ЮЖ>  A();

ЮЖ>  A(A&);

ЮЖ>  template<class T>
ЮЖ>  A(const T&)
ЮЖ>  {}
ЮЖ>};

ЮЖ>struct B : A
ЮЖ>{
ЮЖ>  B();
ЮЖ>};

ЮЖ>int main()
ЮЖ>{
ЮЖ>  B b;
ЮЖ>  B b1 = b; // error
ЮЖ>}


Можно уточнить, какого типа ошибка подразумевалась в строке B b1 = b; — логическая или синтаксическая?
Re[7]: Конструктор копирования из шаблонного типа
От: Юрий Жмеренецкий ICQ 380412032
Дата: 18.08.09 02:59
Оценка:
Здравствуйте, ilvi, Вы писали:
...
I>Можно уточнить, какого типа ошибка подразумевалась в строке B b1 = b; — логическая или синтаксическая?
Пример не показывает то что задумывалось, там моя 'ошибка'.
Re[7]: Конструктор копирования из шаблонного типа
От: Юрий Жмеренецкий ICQ 380412032
Дата: 18.08.09 04:07
Оценка:
Здравствуйте, jazzer, Вы писали:
...
J>Единственное соображение — то, что ты цитируешь, вырвано из абзаца, в котором говорится про конструктор вида Х(Х), посему я настаиваю, что и цитата относится только к этому виду конструктора.

Да, похоже ты прав, цитата относится к конкретному виду. Тот смысл, который я на нее возлагал размазался по другим частям стандарта. Хотя после чтения дефектов складывается ощущение, что с терминологий в этой области стандарта бардак.
Re[6]: Конструктор копирования из шаблонного типа
От: jazzer Россия Skype: enerjazzer
Дата: 18.08.09 06:01
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Может быть, может быть, я не смотрел стандарт, времени нету сейчас совсем.

J>Просто суть этой оптимизации в том, чтоб разрешить избавляться от временных объектов там, где они не нужны.
J>Имхо, это как раз такой случай (по крайней мере, я навскидку не вижу принципиальных препятствий), но он вполне может быть и не прописан в стандарте явно.

Посмотрел стандарт.
То, что нечто не прописано явно, большой роли не играет: достаточно сравнить С++03 с его двумя пунктами и С++0х с четырьмя (это без ссылок на значения), так что дописать отсутствующие пункты не проблема.

Но там еще есть очень неприятный запрет:

...when a temporary class object that has not been bound to a reference...

и этот запрет убивает всё: если у нас ссылка (как раз наш случай), то временный объект никогда не будет изничтожен.

Пока что мне этот запрет кажется слишком сильным, поскольку закрывает возможности для таких оптимизаций, мне надо подумать, почему он такой есть (т.е. какой осмысленный код сломается, если этот запрет снять полностью или частично).
Потому что в приведенном примере с конструктором я не вижу проблем.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Конструктор копирования из шаблонного типа
От: sokel Россия  
Дата: 18.08.09 06:06
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Данный случай не подпадает под условия 12.8/15, поэтому исполнение действий, осуществляемых в копирующем конструкторе, может быть устранено только при условии, что observable behavior будет таким же, как если бы ничего не устранялось, и компилятор умеет это обнаруживать. (В случаях же, подпадающих под условия 12.8/15, устранение вызова копирующего конструктора может на вполне законных основаниях менять observable behavior — следовательно, такой вид оптимизации производить гораздо проще)


А почему не попадает под условия 12.8/15? Разве это не этот случай:

When certain criteria are met, an implementation is allowed to omit the copy construction of a class object,
even if the copy constructor and/or destructor for the object have side effects.
...
— when a temporary class object that has not been bound to a reference (12.2) would be copied to a class
object with the same cv-unqualified type, the copy operation can be omitted by constructing the temporary
object directly into the target of the omitted copy

Re[6]: Конструктор копирования из шаблонного типа
От: jazzer Россия Skype: enerjazzer
Дата: 18.08.09 09:11
Оценка:
Здравствуйте, sokel, Вы писали:

S>А почему не попадает под условия 12.8/15? Разве это не этот случай:

S>

S>When certain criteria are met, an implementation is allowed to omit the copy construction of a class object,
S>even if the copy constructor and/or destructor for the object have side effects.
S>...
S>— when a temporary class object that has not been bound to a reference (12.2) would be copied to a class
S>object with the same cv-unqualified type, the copy operation can be omitted by constructing the temporary
S>object directly into the target of the omitted copy


http://www.rsdn.ru/forum/cpp/3507040.1.aspx
Автор: jazzer
Дата: 18.08.09
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[8]: Конструктор копирования из шаблонного типа
От: Николай Ивченков  
Дата: 18.08.09 14:14
Оценка:
Юрий Жмеренецкий:

ЮЖ>В core language active issue #535 "Copy construction without a copy constructor" предлагают заменить эту строку следующей:


ЮЖ>

if the subobject is of class type, direct-initialization (8.5 [dcl.init]) is performed

ЮЖ>Там же предлагается еще 13 подобных исправлений.

Так что мы имеем насчёт "ЮЖ>>Но ведь это инициализация, а не копирование"? Копирование там или не копирование?

НИ>>А как формируется set of candidate functions при инициализации x2? Где в стандарте можно увидеть внятное объяснение?


ЮЖ>Что-то вроде такого:

ЮЖ>13.3.1.3/1:
ЮЖ>

For direct-initialization, the candidate functions are all the constructors of the class of the object being initialized.


ЮЖ>Варианты:

ЮЖ>1) X(const X&)
ЮЖ>2) X(X)

ЮЖ>Аргумент — volatile lvalue


ЮЖ>

13.3.1/2
ЮЖ>For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.

ЮЖ>Итого:

ЮЖ>1) volatile X -> const X&

ЮЖ>2) volatile X -> X

ЮЖ>Оба варианта в конечном итоге не могут быть использованы из-за C.1.8:


ЮЖ>

The implicitly-declared copy constructor and implicitly-declared copy assignment operator cannot make a copy of a volatile lvalue


Пункт C.1.8 не является нормативным. Копирующий конструктор не является viable function в силу того, что тип const X не является reference-compatible с volatile X. А вот по каким правилам полученная специализация X(X) не является viable function, пока что неясно.
Re: Что поменяется если разкоментировать explicit?
От: minorlogic Украина  
Дата: 18.08.09 14:21
Оценка:
Что поменяется если разкоментировать explicit?
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[9]: Конструктор копирования из шаблонного типа
От: Юрий Жмеренецкий ICQ 380412032
Дата: 19.08.09 03:22
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Так что мы имеем насчёт "ЮЖ>>Но ведь это инициализация, а не копирование"? Копирование там или не копирование?


12.1/2
A constructor is used to initialize objects of its class type.

Инициализация 'from a copy' выполняется с помощью copy ctor'ов. Вот это я называя 'копированием' (не рассматривая assignment). Так же, во всех местах где описываются возможные оптимизации связанные с copy elision, — везде фигурируют именно конструкторы копирования.

НИ>Пункт C.1.8 не является нормативным. Копирующий конструктор не является viable function в силу того, что тип const X не является reference-compatible с volatile X.

Разумеется C.1.8 не на пустом месте стоит.

НИ>А вот по каким правилам полученная специализация X(X) не является viable function, пока что неясно.

Так же как и в случае с обычными функциями. Преобразование volatile X -> X можно выполнить с помощью X:(const volatile& X) и введением временного объекта (это не приведет к рекурсии), но такого конструктора у нас нет. Причем для копирования временного объекта используются только конструкторы копирования — 12.2/4 (template ctor'ы не рассматриваются). Но если бы конструктор X:(const volatile& X) существовал, то был бы использован сразу.
Re[7]: Конструктор копирования из шаблонного типа
От: sokel Россия  
Дата: 19.08.09 08:11
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Пока что мне этот запрет кажется слишком сильным, поскольку закрывает возможности для таких оптимизаций, мне надо подумать, почему он такой есть (т.е. какой осмысленный код сломается, если этот запрет снять полностью или частично).

J>Потому что в приведенном примере с конструктором я не вижу проблем.

Я думаю, тут получаются сложности со временем жизни этого temporary object. То есть, в случае того же конструктора, компилятор должен дополнительно учесть что он нигде, кроме как в списке инициализации, не участвует. А это в стандарте уже сложнее формализовать.
Re[8]: Конструктор копирования из шаблонного типа
От: jazzer Россия Skype: enerjazzer
Дата: 19.08.09 08:42
Оценка:
Здравствуйте, sokel, Вы писали:

S>Здравствуйте, jazzer, Вы писали:


J>>Пока что мне этот запрет кажется слишком сильным, поскольку закрывает возможности для таких оптимизаций, мне надо подумать, почему он такой есть (т.е. какой осмысленный код сломается, если этот запрет снять полностью или частично).

J>>Потому что в приведенном примере с конструктором я не вижу проблем.

S>Я думаю, тут получаются сложности со временем жизни этого temporary object. То есть, в случае того же конструктора, компилятор должен дополнительно учесть что он нигде, кроме как в списке инициализации, не участвует. А это в стандарте уже сложнее формализовать.


формализовать как раз просто.
Если временный объект используется только для того, чтоб проинициализировать другой объект того же типа, то такой временный объект может быть изничтожен. И все. Это включает в себя и нынешние copy elision.
Если компилятор способен этот случай детектировать — все супер, пусть убивает нафиг.
Не способен — ну что ж, никто и не обещал, что оптимизация всегда будет работать.
Другое дело, если этот объект протаскивается через цепочку вызовов — тут надо подумать, можно ли сформулировать корректно.
Надо думать, придумывать разные хитрые примеры, когда хорошо изничтожать, а когда плохо, а у меня сейчас времени нету
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[10]: Конструктор копирования из шаблонного типа
От: Николай Ивченков  
Дата: 19.08.09 12:26
Оценка:
Юрий Жмеренецкий:

НИ>>Так что мы имеем насчёт "ЮЖ>>Но ведь это инициализация, а не копирование"? Копирование там или не копирование?


ЮЖ>

12.1/2
ЮЖ>A constructor is used to initialize objects of its class type.

ЮЖ>Инициализация 'from a copy' выполняется с помощью copy ctor'ов. Вот это я называя 'копированием' (не рассматривая assignment).

В данном случае меня интересует, что копированием называет стандарт. Судя по приведённым ссылкам, одними копирующими конструкторами здесь дело не ограничивается. Поэтому с замечанием "Но ведь это инициализация, а не копирование" я согласиться не могу.

НИ>>А вот по каким правилам полученная специализация X(X) не является viable function, пока что неясно.

ЮЖ>Так же как и в случае с обычными функциями. Преобразование volatile X -> X можно выполнить с помощью X:(const volatile& X) и введением временного объекта (это не приведет к рекурсии), но такого конструктора у нас нет.

Инициализацию аргумента специализации X(X) можно осуществить с помощью этой же самой специализации. Так что механизм исключения специализации X(X) из рассмотрения остаётся неясен. Такое исключение может произойти как на этапе формирования set of candidate functions, так и на этапе формирования set of viable functions. Ничего внятного по этому вопросу я в стандарте не вижу.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.