6 / 29 / 9
Регистрация: 13.05.2015
Сообщений: 1,835
|
|||||||||||||||||||||
1 | |||||||||||||||||||||
Почему в данном случае срабатывает неявный конструктор15.02.2018, 01:20. Просмотров 1121. Ответов 20
Метки нет Все метки)
(
Почему в данном случае срабатывает неявный конструктор, хотя он и помечен explicit?
Main.cpp:
Взял отсюда: https://stackoverflow.com/ques... 03#4285803. Добавлено через 8 минут После дебага заметил что тут выходит почему-то одновременно с вызовом конструктора:
0
|
|
15.02.2018, 01:20 | |
[C]Почему bind в данном случае выдаёт ошибку Address already in use? |
|
С чаем беда...
![]() ![]() 8061 / 3946 / 1088
Регистрация: 18.10.2014
Сообщений: 8,483
|
|
15.02.2018, 01:39 | 2 |
Ничего не понятно. У вас в коде нет никаких предпосылок для использования вашего
explicit конструктора. С чего вы взяли, что он у вас "срабатывает"? Где?У вас в коде открытым тестом прописано использование конструктора HugoCopy(Hugo const& hugo) и оператора operator Hugo const&() . А они никакие не explicit .
1
|
Don't worry, be happy
|
||||||
15.02.2018, 01:51 | 3 | |||||
TheCalligrapher, думаю, он о том, что
1
|
С чаем беда...
![]() ![]() 8061 / 3946 / 1088
Регистрация: 18.10.2014
Сообщений: 8,483
|
|
15.02.2018, 02:02 | 4 |
Хм... В данном случае преобразование
HugoCopy обратно в Hugo делается через operator Hugo const&() , т.е. с преобразованием как таковым проблем нет. У меня этот код прекрасно собирается и в gcc и в clang. Более того, даже если добавить Hugo p = f(); в main , то код собирается gcc в режиме C++17, но не собирается в режиме C++14 (именно из-за конструктора копирования), что по-видимому вызвано guaranteed copy elision в C++17.Добавлено через 3 минуты Хотя да, вижу что конструктор копирования вызывается в gcc...
1
|
Don't worry, be happy
|
|
15.02.2018, 02:03 | 5 |
Но для построения объекта необходим конструктор копирования, который explicit.
gcc: http://rextester.com/FRWIK38971 vc: http://rextester.com/FNLWAA35042
1
|
Комп_Оратор)
![]() |
||||||
15.02.2018, 02:09 | 6 | |||||
У меня не компилируется. Я думаю это потому что f возвращает не ссылку а копию. А конструктора допускающего преобразование нет.
То есть, константная ссылка на локальный объект потребует копирования для возврата из такой функции. Например можно и так написать. Тут явно видно что происходит. Не желает конструктор копии преобразовывать константную ссылку в аргумент требующий Hugo h. Тут конечно забавно всё выглядит так как объявлен то он именно как ссылка на константу. Но объявление ссылки аргумента функции это не объявление типа, а декларация контракта - не менять аргумент. В функции инициализируется ссылка, но ожидается внешний объект. Это поведение касается именно константной ссылки.
![]() Не по теме: Пардон. До моего поста выступлений ещё не было. Впрочем, я уверен в том, что говорю не менее чем обычно. То есть сомневаюсь как всегда. :pardon:
0
|
41 / 74 / 15
Регистрация: 04.10.2017
Сообщений: 284
|
|
15.02.2018, 02:24 | 8 |
oobarbazanoo, потому что hugo надо заменить на hoggy.
4
|
IGPIGP
|
15.02.2018, 02:27
#9
|
0
|
Don't worry, be happy
|
|
15.02.2018, 02:27 | 10 |
TheCalligrapher, в return statement должна быть copy-initialization.
explicit Hugo(Hugo const&) не должен быть кандидатом, но если return HugoCopy(h) собирается, значит в return statement используется не copy-initialization, верно?
1
|
6 / 29 / 9
Регистрация: 13.05.2015
Сообщений: 1,835
|
|
15.02.2018, 14:46 [ТС] | 11 |
tmpValue, почему на hoggy? Не нахожу перевода или значения данного слова. Объясните данный момент, пожалуйста.
Добавлено через 1 минуту Croessmah, в этом то и вопрос. Как? Добавлено через 4 минуты Croessmah, подскажите, пожалуйста, как Вы смогли сделать так, что бы Ваш код сохранился для тех кто перейдёт по ссылке на онлайн компилятор?
0
|
Don't worry, be happy
|
|
15.02.2018, 17:10 | 12 |
Может у него и спросим? hoggy, выходи, дорогой.
![]() Как правило, облачные компиляторы умеют это. Где-то кнопочка save, где-то fork, где-то share... Добавлено через 1 минуту Ну так мне тоже интересно. Возможно, TheCalligrapher, сможет объяснить. ![]() Или DrOffset, или ct0r. На удачу позову еще FoReVeR и Tulosba.
1
|
![]() 8274 / 3850 / 837
Регистрация: 15.11.2014
Сообщений: 8,726
|
|
15.02.2018, 19:07 | 13 |
1
|
Комп_Оратор)
![]() |
|||||||||||
15.02.2018, 19:16 | 14 | ||||||||||
Дык и не компилится. Однако не ясно почему вот так:
Оно же и при возврате из функции по значению получается неявным вызовом... Ну то есть, такое чувство, что гарантия что не появится приведение только при вызове:
Понимаю что бредово, но вот как ещё это можно объяснить?
1
|
Don't worry, be happy
|
|
15.02.2018, 19:31 | 15 |
Потому что по правилам языка в direct-initialization
A a(b) explicit конструкторы будут рассматриваться как кандидаты при выборе конструктора, а в copy-initialization A a = b; explicit-конструкторы не являются кандидатами.Добавлено через 44 секунды clang собирает
0
|
Комп_Оратор)
![]() |
|
15.02.2018, 19:42 | 16 |
Вот-вот. Словосочетание "правилам языка" - ключевое. Это в общем и целом означает "потому что". Фактически операторная форма вызова:
A a= b; однозначно эквивалентна A a(a); и не должно быть разницы. Различие то тут (насколько я понимаю) только в синтаксисе, а вызов то однозначен? Просто компиллятору нужно бы быть чуть-чуть умнее. и выясняется, что такой компилятор есть. Странно это. Но нужно запомнить. ![]()
0
|
Комп_Оратор)
![]() |
|
15.02.2018, 19:50 | 18 |
Я имел ввиду случай когда есть определённый пользователем конструктор копии (тот что в топике случай). Конструктор преобразования с аргументом своего типа, то есть. Насколько мне известно при вызове:
A a=b; должен вызваться именно он и ни какой другой. Если это не так, то это и есть ответ на вопрос топика.
0
|
284 / 175 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
|
29.04.2018, 03:24 | 19 |
Не всё так однозначно. Конечно,
return e — это copy-initialization.Только вот в зависимости от типа (и value category) e правила разные.В данном случае, возвращаемый тип у функции — это тип-класс. Поэтому смотрим в ![]() e — тот же (игнорируя cv-квалификаторы) тип-класс, что и инициализируемый (возвращаемый), и e это не prvalue (пункт (17.6.1)), то применяется (17.6.2) и, конечно, explicit-конструктор не подойдёт.Но в случае return HugoCopy(h) действует пункт (17.6.3)Пункт ссылается на [over.match.copy] ![]() Hugo нет.(1.2) даёт нам candidate function HugoCopy::operator Hugo const& .Эта функция, с аргументом HugoCopy(h) , используется для инициализации: "The call is used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization".Это свежий драфт. В драфте n1905 от 2005-го года сказано, в принципе, то же самое: Добавлено через 22 часа 59 минут Самое забавное, что Croessmah 2.5 года назад цитировал нужное место стандарта и даже подчеркнул: но в этом топике старательно всех убеждает, что код компилироваться не должен.
0
|
Комп_Оратор)
![]() |
|
29.04.2018, 08:42 | 20 |
Последнее, скорее всего относится к копи-элизиум оптимизации и к данному случаю не относится. Я не уверен, потому и пишу "скорее всего". В нашем случае (опять же - по идее) имеет место быть возможность прямого указания компилятору - применять копирующий конструктор только для случаев его явного вызова. Это может быть нужно, например, когда операция присаивания и копирующий конструктор работают с ресурсами по разному.
0
|
29.04.2018, 08:42 | |
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.
Почему в данном случае ставится двойной нижний пробел __ в цикле for?
Почему не срабатывает конструктор копирования в пользовательском классе Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |