Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Tulosba
:)
Эксперт С++
4390 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
#1

Доступность копирующего конструктора - C++

18.11.2013, 18:07. Просмотров 403. Ответов 6
Метки нет (Все метки)

Всем привет.

Не так давно в одной из тем была упомянута статья Герба Саттера Variable Initialization – or Is It?.

По статье остался не понятен момент в п.1 при описании кода (f), (g). В частности абзац:

Note that I said “conceptually” a few times above. That’s because practically compilers are allowed to, and routinely do, optimize away the temporary and, if an implicit conversion is available, convert (f) to (d), thus optimizing away the extra move operation. However, even when the compiler does this, the widget copy constructor must still be accessible, even if is not called—the copy constructor’s side effects may or may not happen, that’s all.
Правильно ли я понял, что для случая:
C++
1
widget w = x;
даже когда компилятор может убрать лишние вызовы конструкторов, копирующий конструктор (даже если он не вызывается) должен быть доступен?

Если я понял правильно, то это не совсем соответствует действительности:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
class C
{
public:    
    C() { cout << "C()" << endl; }
    C( int ) { cout << "implicit C(int)" << endl; }
    C( C&& ) { cout << "C(C&&)" << endl; }
    C& operator= ( const C& ) { cout << "operator=" << endl; return *this; }
    //C( const C& ) { cout << "C(const C&)" << endl; }
private:
    C( const C& ) = delete; 
    //C( C&& ) = delete;
};
 
int main() {
    C c1 = 10;
    return 0;
}
Вызывает только один конструктор с целым аргументом:
http://coliru.stacked-crooked.com/a/07558605af3d97b0

Добавляем опцию --no-elide-constructors и получаем еще вызов конструктора перемещения:
http://coliru.stacked-crooked.com/a/ab8813cbab372651

И если теперь убрать конструктор перемещения:
C++
1
C( C&& ) = delete;
, то будет ошибка:
http://coliru.stacked-crooked.com/a/00751bae83617dec
use of deleted function 'C::C(C&&)'
Ну и если снова убрать --no-elide-constructors получим ту же ошибку:
http://coliru.stacked-crooked.com/a/235703e12a3039fd

Т.е. получается, что Саттер вроде как прав, но речь должна идти о конструкторе перемещения, а не копирования.

Поправьте меня, если я не прав.

Заранее спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.11.2013, 19:07     Доступность копирующего конструктора #2
думаю он и говорит о конструкторе перемещения в своей статье:
the compiler first implicitly converts x to a temporary widget object, then move-constructs w from that temporary rvalue, using copy construction as “the slow way to move” as a backup if no better move constructor is available
Tulosba
:)
Эксперт С++
4390 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.11.2013, 19:19  [ТС]     Доступность копирующего конструктора #3
retmas, похоже в одном абзаце (который привели Вы) Саттер говорит правильно, а в следующем (на котором сделал акцент я) уже почему-то copy constructor. Наверное просто опечатался.
retmas
Жарю без масла
859 / 741 / 164
Регистрация: 13.01.2012
Сообщений: 1,694
18.11.2013, 19:26     Доступность копирующего конструктора #4
может быть, но мне думается, что он не опечатался. поясню. вот из вашего отрывка:
thus optimizing away the extra move operation. However, even when the compiler does this, the widget copy constructor must still be accessible, even if is not called
здесь говорится о том, что опускается вызов мув конструктора при оптимизации. но не смотря на это он должен существовать. думаю "copy constructor" здес был не конкретный термин, а обобщение.
может я неверно понял. ваши соображения?
ct0r
Игогошка!
1760 / 662 / 42
Регистрация: 19.08.2012
Сообщений: 1,261
Завершенные тесты: 1
18.11.2013, 23:31     Доступность копирующего конструктора #5
then move-constructs w from that temporary rvalue, using copy construction as “the slow way to move” as a backup if no better move constructor is available
thus optimizing away the extra move operation. However, even when the compiler does this, the widget copy constructor must still be accessible, even if is not called—the copy constructor’s side effects may or may not happen, that’s all.
Саттер все правильно сказал. Он ведет речь о случае, в котором у класса нет конструктора перемещения (или он const &&), а в этом случае используется конструктор копирования (так как нет более подходящих перегрузок) как "медленный мув". Поэтому конструктор копирования должен быть определен, даже в случае copy-elision.
Tulosba
:)
Эксперт С++
4390 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
19.11.2013, 12:15  [ТС]     Доступность копирующего конструктора #6
Цитата Сообщение от ct0r Посмотреть сообщение
о случае, в котором у класса нет конструктора перемещения (или он const &&), а в этом случае используется конструктор копирования
ct0r, при наличии copy-конструктора и отсутствии move-конструктора всё равно ошибка:
http://coliru.stacked-crooked.com/a/856c4238243ad836
Если Вы имели в виду что-то другое, пожалуйста, приведите код, подтверждающий Ваши слова.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2013, 13:02     Доступность копирующего конструктора
Еще ссылки по теме:

C++ Вызов копирующего конструктора
Доступность полей при чтении из файла C++
C++ Вызов конструктора
C++ Какой должен быть прототип у оператора копирующего присваивания?
Проверить доступность компьютера в сети C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ct0r
Игогошка!
1760 / 662 / 42
Регистрация: 19.08.2012
Сообщений: 1,261
Завершенные тесты: 1
19.11.2013, 13:02     Доступность копирующего конструктора #7
Цитата Сообщение от Tulosba Посмотреть сообщение
при наличии copy-конструктора и отсутствии move-конструктора всё равно ошибка:
По умолчанию мув-конструктора нет (если точнее, то он может быть, но при выполнении целого ряда условий). Потому что иначе старый код может перестать работать. А там ты его объявляешь. delete-функция - это объявленная функция без определения. Поэтому он начинает участвовать в разрешении перегрузки. Надо удалить его нафиг.
http://coliru.stacked-crooked.com/a/8111a130895076c9
Yandex
Объявления
19.11.2013, 13:02     Доступность копирующего конструктора
Ответ Создать тему
Опции темы

Текущее время: 09:53. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru