powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Помогите не понимаю
18 сообщений из 43, страница 2 из 2
Помогите не понимаю
    #39638251
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCcГлупости.

В каком месте?

OoCcв 99% случаях замена вектора на декъю решает все проблемы с внутренними перемещениями и лишними обьектами.
Да, дек лишён некоторых недостатков вектора -- вставки в начало и в конец не инвалидируют итераторы, так же как и удаление, так как в памяти он хранится в виде двумерного массива, а не полностью непрерывно, как вектор. Однако тут сразу встаёт вопрос со вставкой элемента в середину, а также вопрос кэширования данных дека CPU. Так что, ни то, ни другое -- не панацея, везде надо искать компромиссы для своего конкретного случая. И в случае с вектором из ваших классов можно значительно уменьшить накладные расходы на реаллокацию реализовав правильно move-конструктор.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639134
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZИли можно сделать noexcept move-конструктор. Именно такой будет вызываться при реаллокации вектора, если существует, взамен конструктору копирования.При релокации вектора (при исчерпании зарезервированного места) вызываются конструкторы? Не верю. Для "пользователя" это вообще невидимое событие, чисто технически необходимое, перенос куска памяти (набора указателей в случае вектора) в новое место.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639144
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbПри релокации вектора (при исчерпании зарезервированного места) вызываются конструкторы? Не верю. Для "пользователя" это вообще невидимое событие, чисто технически необходимое, перенос куска памяти (набора указателей в случае вектора) в новое место.
Ну приехали... Может, стоило хотя бы проверить?

Просто запусти этот код и проверь (обещаю, он не майнит биткойны):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
#include <iostream>
#include <vector>

using namespace std;

struct S
{
    S() { puts("S()"); }
    S(S const &) { puts("S(S const &)"); }
    S& operator=(S const &) { puts("operator=(S const &)"); return *this; }
    
    S(S &&) { puts("S(S &&)"); }
    S& operator=(S &&) { puts("operator=(S &&)"); return *this; }
};

int main(int, char** )
{
    vector<S> v;
    cout << "capacity=" << v.capacity() << "\n";
    v.emplace_back();
    cout << "capacity=" << v.capacity() << "\n";
    v.emplace_back();
    cout << "capacity=" << v.capacity() << "\n";
    v.emplace_back();
    cout << "capacity=" << v.capacity() << "\n";
    return 0;
}



У меня получился такой вывод:

capacity=0
S()
capacity=1
S()
S(S const &)
capacity=2
S()
S(S const &)
S(S const &)
capacity=4
Program ended with exit code: 0

Попробуй объяснить каждую строчку вывода.
Имеем три вызова дефолтного конструктора и три вызова конструктора копирования.

А потом, если ты просто добавишь noexcept к move-конструктору, то будет вызываться именно он:

capacity=0
S()
capacity=1
S()
S(S &&)
capacity=2
S()
S(S &&)
S(S &&)
capacity=4
Program ended with exit code: 0
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639398
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZПросто запусти этот код и проверь
А, блин, я понял, в чём дело (но успел посмотреть код под двумя компиляторами), ну да, всё верно, там потому что в векторе хранятся объекты. Поэтому при релокации, stl будет их переносить, потому что по-другому просто не умеет. А если std::move есть, то да, можно и не переносить (к чему и стремились), потому что сами объекты по сути не меняются.

я не заметил подвох потому что обычно так: vector<S> не делаю (а стоило, видимо. "В жизни нужно попробовать всё")

единственное, прошу разъяснить, как noexcept влияет на выбор конструктора. У меня (С++11) без noexept вызывался move-конструктор.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639437
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbединственное, прошу разъяснить, как noexcept влияет на выбор конструктора. У меня (С++11) без noexept вызывался move-конструктор.
ЕМНИП, не noexcept move-конструктор будет вызываться только тогда, когда нет вообще доступного конструктора копирования и есть явно заданый move-конструктор без noexcept'а.
То есть, приоритет выбора такой, сверху вниз:
1. noexcept move-ctor
2. copy-ctor
3. move-ctor
4. error
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639444
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbтам потому что в векторе хранятся объекты.
Логично. Для POD-типов, включая сырые указатели, ты не переопределишь move-конструктор. В таких случаях, вектор просто делает memmove, что как бы намекает ;-)
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639738
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZЛогично.Логично то, что один раз закинув объект в вектор, я не должен ожидать повторный вызов конструктора для него, так как сам я объект не перемещаю, да и при растяжении вектора объект перемещаться не должен в идеале.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639740
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbпри растяжении вектора объект перемещаться не должен в идеале.
Как тогда можно увеличить размер вектора, сохранив последовательное расположение его элементов в памяти? Чудес не бывает.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639750
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbNekZЛогично.Логично то, что один раз закинув объект в вектор, я не должен ожидать повторный вызов конструктора для него, так как сам я объект не перемещаю, да и при растяжении вектора объект перемещаться не должен в идеале.
Может, тогда тебе нужен другой контейнер, например, std::list?
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639758
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZМожет, тогда тебе нужен другой контейнер, например, std::list?да не, я просто в векторах указатели/POD храню, так что всё ок.

Но я действительно не ожидал, что будет вызываться конструктор при переносе внутренностей вектора. Почему бы не перенести байт-в-байт данные?
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639761
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbПочему бы не перенести байт-в-байт данные?
Например там может быть указатель на буфер внутри объекта. Недавно обсуждали глюк с std::string .
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39639762
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНапример там может быть указатель на буфер внутри объекта.Спасибо, вопрос снят
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39640355
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbда не, я просто в векторах указатели/POD храню, так что всё ок.

Тогда ты всё равно должен помнить, что если хранишь умные указатели в векторе, у них, скорее всего, иногда вызывается move-ctor ;-)
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39640570
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbя просто в векторах указатели/POD храню
ну а сами объекты размещаются на куче черти где, и последовательный перебор будет со скоростью работы памяти(раза в 3-4 медленнее, чем могло бы)?
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39641174
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZдолжен помнитьда, теперь буду!
alex_kну а сами объекты размещаются на куче черти где, и последовательный перебор будет со скоростью работы памяти(раза в 3-4 медленнее, чем могло бы)?надо проверить. По идее, не сильно медленнее должно быть, что стек, что куча? В случае с кучей просто ещё одна операция разыменования (а я обычно в начале цикла сразу беру указатель с итератора и работаю уже с ним), и всё упирается в то, как мы работаем с объектом.
Ну, идеального решения на все случаи в плюсах нету. Если вектор часто переносится - выгоднее, видимо, держать указатели. Если нет - объекты.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39641326
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbalex_kну а сами объекты размещаются на куче черти где, и последовательный перебор будет со скоростью работы памяти(раза в 3-4 медленнее, чем могло бы)?надо проверить. По идее, не сильно медленнее должно быть, что стек, что куча? В случае с кучей просто ещё одна операция разыменования (а я обычно в начале цикла сразу беру указатель с итератора и работаю уже с ним), и всё упирается в то, как мы работаем с объектом.
Ну, идеального решения на все случаи в плюсах нету. Если вектор часто переносится - выгоднее, видимо, держать указатели. Если нет - объекты.
Тут, наверное, имелся в виду перенос данных в кэши процессора, когда ты последовательно обращаешься к непрерывному куску памяти, что намного ускоряет выполнение кода. А когда данные по памяти разбросаны по указателям, то прироста скорости не жди.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39641744
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZА когда данные по памяти разбросаны по указателям, то прироста скорости не жди.в случае, когда вектор шибко динамический, без указателей, но с большими объектами, то прирост скорости может и быть за счёт переноса только указателей, а не объектов.
...
Рейтинг: 0 / 0
Помогите не понимаю
    #39642158
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbNekZА когда данные по памяти разбросаны по указателям, то прироста скорости не жди.в случае, когда вектор шибко динамический, без указателей, но с большими объектами, то прирост скорости может и быть за счёт переноса только указателей, а не объектов.

Это очень тонкий трейд-оф
...
Рейтинг: 0 / 0
18 сообщений из 43, страница 2 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Помогите не понимаю
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]