powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Размещение в контейнерах STL не копируемых объектов
33 сообщений из 33, показаны все 2 страниц
Размещение в контейнерах STL не копируемых объектов
    #39966736
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, конечно, знаю, что в общем случае так делать нельзя. Но всё же, если мы не вызываем методы контейнера, которые приводят к копированию, то почему бы и нет? Вот нужно добиться такого функционала:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
class NonCopyAble
{
protected:

    NonCopyAble() = default;

private:

    NonCopyAble(NonCopyAble const &) = delete;
    NonCopyAble &operator=(NonCopyAble const &) = delete;

};

void testNonCopy()
{
    std::vector<NonCopyAble> vec;
    vec.resize(3);
}


Я понимаю, что тут в resize() цикл по копированию элементов. Можно ли это как-то обойти? Ведь мне не нужно копирование. Нужно разместить N элементов, причём N неизвестно на этапе компиляции. С точки зрения С++ сделать это можно. Но вот с точки зрения STL?
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966739
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravНо всё же, если мы не вызываем методы контейнера, которые приводят к копированию, то
почему бы и нет?

К копированию приводит любой метод помещения объекта в контейнер. Контейнер, в который
нельзя поместить объекты - бесполезен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966741
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravНо всё же, если мы не вызываем методы контейнера, которые приводят к копированию, то
почему бы и нет?

К копированию приводит любой метод помещения объекта в контейнер. Контейнер, в который
нельзя поместить объекты - бесполезен.

Да, нет, возможно. Я не додумал. Хоть это и не совсем то что мне нужно. Вот если бы создать std::vector конструктором по умолчанию, пустым. А потом сделать resize(). Но вот это уже невозможно, ведь при компиляции resize() неизвестно ведь пустой вектор или нет. Ну да... не очень удобно.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
class NonCopyAble
{
public:

    NonCopyAble() = default;

private:

    NonCopyAble(NonCopyAble const &) = delete;
    NonCopyAble &operator=(NonCopyAble const &) = delete;

};

void testNonCopy()
{
    size_t N = 3;
    NonCopyAble *arr = new NonCopyAble[N]();
    delete[] arr;

    std::vector<NonCopyAble> vec(N);
}
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966744
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Значит лёгким движением руки некопируемый объект превращается в копируемый:
Код: sql
1.
std::vector<std::shared_ptr<NonCopyAble>> vec;


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966747
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поместить в вектор некопируемый объект можно при помощи emplace_back.
Только надо сделать некопируемый объект - перемещаемым(moveable).
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966764
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_k
Поместить в вектор некопируемый объект можно при помощи emplace_back.
Только надо сделать некопируемый объект - перемещаемым(moveable).

Сильно сомневаюсь.

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.
Это же означает копирование вектора (элементов), если у нас зарезервированное место закончилось.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966766
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

зачем их копировать? их надо перенести
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966769
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Значит лёгким движением руки некопируемый объект превращается в копируемый:
Код: sql
1.
std::vector<std::shared_ptr<NonCopyAble>> vec;



Тогда уж так:

Код: plaintext
1.
auto vec = std::make_unique<std::vector<NonCopyAble>>(N);


Мне не нужно добавлять/удалять элементы.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966771
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Мне не нужно добавлять/удалять элементы.

std::shared_ptr это умный указатель, сам объект никуда не перемещается.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966775
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravМне не нужно добавлять/удалять элементы.

Тогда назачем тебе вообще вектор?
Код: sql
1.
std::unique_pointer<NonCopyAble[]> = new NonCopyAble[N];


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966778
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravМне не нужно добавлять/удалять элементы.

Тогда назачем тебе вообще вектор?
Код: sql
1.
std::unique_pointer<NonCopyAble[]> = new NonCopyAble[N];



Я не пользуюсь оператором [], только метод at().
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966779
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_k
petrav,

зачем их копировать? их надо перенести

Да это мысль. Наверное, нужно написать конструктор/оператор перемещения, к сожалению, не очень в этом разбираюсь.

Но тут дело в чём? Вот эти не копируемые объекты по сути представляют собой набор байт. Т.е. это почти POD, эти объекты можно скопировать с помощью std::memcpy(). Но по логике программы их копировать не нужно; из перфекционизма я хочу запретить их копирование. Но если пойти по пути предложенном вами и написать эти конструктор и оператор перемещения, то... они начнут копироваться внутри std::vector!

Я может что-то не понимаю, но такой вот философский момент возникает для рассмотрения. :)
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966780
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
alex_k
petrav,

зачем их копировать? их надо перенести

Да это мысль. Наверное, нужно написать конструктор/оператор перемещения, к сожалению, не очень в этом разбираюсь.

Но тут дело в чём? Вот эти не копируемые объекты по сути представляют собой набор байт. Т.е. это почти POD, эти объекты можно скопировать с помощью std::memcpy(). Но по логике программы их копировать не нужно; из перфекционизма я хочу запретить их копирование. Но если пойти по пути предложенном вами и написать эти конструктор и оператор перемещения, то... они начнут копироваться внутри std::vector!

Почитай Мейерса , тоненькая книжка, перемещение это не копирование, а просто компилятор делает так что сразу пишешь туда куда перемещаешь, т.е. по факту объект создается в контейнере.
Все это надо для многопоточности, т.к. пока один поток копирует - другой может поменять то что копируется.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966781
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T

Почитай Мейерса , тоненькая книжка, перемещение это не копирование, а просто компилятор делает так что сразу пишешь туда куда перемещаешь, т.е. по факту объект создается в контейнере.
Все это надо для многопоточности, т.к. пока один поток копирует - другой может поменять то что копируется.

Я так понимаю, что конструкторы/операторы перемещения имеют смысл только для классов аля std::string. Когда указатель на char просто копируется в объект-приёмник, а в объекте-источнике зануляется. Это не тот случай.

PS: Да, почитаю.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966830
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravЯ не пользуюсь оператором [], только метод at().

А в чём смысл такого бокса с рукой, привязанной к ноге?

Пользуешься at() - добавь его к unique_ptr, это же всего лишь темплейт.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39966832
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravЯ не пользуюсь оператором [], только метод at().

А в чём смысл такого бокса с рукой, привязанной к ноге?
Для проверки выхода за пределы массива. А что это моветон? :)

Dimitry Sibiryakov
Пользуешься at() - добавь его к unique_ptr, это же всего лишь темплейт.

Тут я вас не понял. Что и куда вы предлагаете добавить?

Просто в вашем варианте N указателей, но мне тут хватит одного.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967206
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
только для классов аля std::string
Вы хотели сказать "для объектов с указателем на динамически аллоцированную память". И не только, так как память не единственный ресурс.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967211
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
petrav
только для классов аля std::string
Вы хотели сказать "для объектов с указателем на динамически аллоцированную память". И не только, так как память не единственный ресурс.

Конечно, любой ресурс с эксклюзивным владением, которое (владение) можно легко передать, забрав у себя. Динамическая память в любом виде, дескриптор файла и т.д. Любой ресурс: сокет, мьютекс (возможно).

Там вообще выше какой-то бардак случился. Кое кто перепутал move семантику с emplace(), кто-то предложил не копировать элементы массива, а переносить. Кто-то даже сказал, что move семантика она для многопоточности... пока один поток пишет, то другой переносит. Короче, там выше бардак.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967213
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

А с чего Вы взяли, что у Вас в исходном варианте в первом посте происходит копирование? Вызов-то resize без второго параметра.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967214
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
petrav,

А с чего Вы взяли, что у Вас в исходном варианте в первом посте происходит копирование? Вызов-то resize без второго параметра.

Наверное потому что если не хватит зарезервированного пространства под новый размер, то вектор придётся (возможно) копировать в другую область памяти?
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967215
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
AmKad
petrav,

А с чего Вы взяли, что у Вас в исходном варианте в первом посте происходит копирование? Вызов-то resize без второго параметра.

Наверное потому что если не хватит зарезервированного пространства под новый размер, то вектор придётся (возможно) копировать в другую область памяти?
Конечно, но опять-таки в Вашем примере вектор на момент resize пустой.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967216
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

Я понял, почему Вам предложили вектор указателей, но не понял, почему Вы вместо этого выбрали указатель на вектор.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967217
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
petrav
пропущено...

Наверное потому что если не хватит зарезервированного пространства под новый размер, то вектор придётся (возможно) копировать в другую область памяти?
Конечно, но опять-таки в Вашем примере вектор на момент resize пустой.

Да, но компилятор, когда компилирует вызов resize(), он-то об этом не знает и начинает компилировать что-то наподобие цикла с operator placement new передавая туда результат std::move(). Я могу ошибаться (и ошибаюсь скорее всего) в деталях. Но смысл в том что в resize() содержится цикл копирования. И компиляция ломается на этом.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967218
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

resize без второго параметра помимо перемещения/копирования существующих объектов еще предполагает и создание новых объектов с вызовом дефолтного конструктора. А он у Вас в protected, а это запрещает создание объекта этого класса.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967219
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad
petrav,

resize без второго параметра помимо перемещения/копирования существующих объектов еще предполагает и создание новых объектов с вызовом дефолтного конструктора. А он у Вас в protected, а это запрещает создание объекта этого класса.

Потому что это цитирование боевого кода (это базовый класс) и, да... я просто не очень хорошо оформил свой первый пример кода. Но во втором моём примере кода эта проблема уже была исправлена.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967220
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все равно не понимаю, чего Вы хотите. Если хотите запретить копирование объекта, то запретите вызов копирующего конструктора. Вместого него определите перемещающий конструктор.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
void f() {
    class NonCopyAble {
        int n = 100500;
    public:
        NonCopyAble() : n(-1) { logDebug("default constructor %d", n); };
        NonCopyAble(int N) : n(N) { logDebug("parameter constructor %d", n); };
        NonCopyAble(NonCopyAble&& rhs) { n = rhs.n; logDebug("move constuctor %d", n); };
        NonCopyAble(const NonCopyAble&) = delete;
        NonCopyAble& operator=(NonCopyAble const&) = delete;
    };

    std::vector<NonCopyAble> vec;

    logDebug("emplace_back.."); vec.emplace_back(0);
    logDebug("emplace_back.."); vec.emplace_back(1);
    logDebug("emplace_back.."); vec.emplace_back(2);
    logDebug("resize..."); vec.resize(6);
};

Вывод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
f                            | emplace_back..
f::NonCopyAble::NonCopyAble  | parameter constructor 0
f                            | emplace_back..
f::NonCopyAble::NonCopyAble  | parameter constructor 1
f::NonCopyAble::NonCopyAble  | move constuctor 0
f                            | emplace_back..
f::NonCopyAble::NonCopyAble  | parameter constructor 2
f::NonCopyAble::NonCopyAble  | move constuctor 0
f::NonCopyAble::NonCopyAble  | move constuctor 1
f                            | resize...
f::NonCopyAble::NonCopyAble  | default constructor -1
f::NonCopyAble::NonCopyAble  | default constructor -1
f::NonCopyAble::NonCopyAble  | default constructor -1
f::NonCopyAble::NonCopyAble  | move constuctor 0
f::NonCopyAble::NonCopyAble  | move constuctor 1
f::NonCopyAble::NonCopyAble  | move constuctor 2
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967222
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AmKad,

Осталось подумать... В случае по сути POD класса различаются ли семантики копирования и перемещения? Вам не кажется, что вы семантику копирования реализовали через "перемещение"? Это как различие между синтаксической и семантической константностью.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967225
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Допустим у нас класс содержит 99-ть полей double. Нам его не нужно копировать по логике программы. Мы ему запретили копирование, но при этом разработали перемещение, которое, по сути, приводит к копированию. Вот есть ли в этом смысл? Сомнительно... Как говорят в определённых кругах: меня терзают смутные сомнения...
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39967431
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

Ты сам себя запутал. Мой пример вырос из твоего. Конечно, в этом случае нет смысла вкорячивать перемещение вместо копирования. Но так как ты настойчиво хотел избежать копирования, я решил, что ты хочешь добиться перемещения (ты же все-таки не зря упомянул std::string), я показал тебе, как это сделать. В конечном итоге, я не понимаю, чего ты хочешь добиться. Возможно и ты тоже.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39981453
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravМне не нужно добавлять/удалять элементы.

Тогда назачем тебе вообще вектор?
Код: sql
1.
std::unique_pointer<NonCopyAble[]> = new NonCopyAble[N];



Кстати, а насколько эта конструкция корректна? Будет корректно выбран оператор delete[]? Насколько я помню, когда-то в Boost был тип shared_ptr_array. Я погуглил и, вроде бы, да это корректно .
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39981468
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravКстати, а насколько эта конструкция корректна?

Ну, если извинить, что я забыл имя переменной и использовал инициализацию присваиванием
вместо круглых скобок, что прокатывает не с каждым компилятором, то почему бы и нет?

petravБудет корректно выбран оператор delete[]?

У параметра темплейта есть квадратные скобки, стало быть и оператор будет использоваться с
квадратными скобками.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39981504
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravКстати, а насколько эта конструкция корректна?

Ну, если извинить, что я забыл имя переменной и использовал инициализацию присваиванием
вместо круглых скобок, что прокатывает не с каждым компилятором, то почему бы и нет?

petravБудет корректно выбран оператор delete[]?

У параметра темплейта есть квадратные скобки, стало быть и оператор будет использоваться с
квадратными скобками.

Просто я не знаю как написать такую специализацию, что бы отреагировала на квадратные скобки. :) Но раз корректно, значит пусть так и будет.
...
Рейтинг: 0 / 0
Размещение в контейнерах STL не копируемых объектов
    #39981514
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravя не знаю как написать такую специализацию, что бы отреагировала на квадратные скобки.

Ну так посмотри как это сделано в STL. Твоя не вызывающая сочувствия IDE, безусловно,
позволит сделать это в один клик.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
33 сообщений из 33, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Размещение в контейнерах STL не копируемых объектов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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