Войти
ПрограммированиеФорумОбщее

non_copyable для полей класса

#0
14:03, 6 дек. 2019

Сказочка:

Накопилось у меня очень много портянок темплейтов и я задумался как бы их проверить на предмет копирования данных - т.е. нигде ли не происходит нежелательного копирования данных, может где std::forward потерялся и прочее.

А темплейты в основном для сериализации/десериализации с кучей специализаций для разных типов, да ещё и монструозные абстрагирующие обёртки над этим надо всем.

А чтоб данные(в основном поля классов) для сериализации передавались без копирования -  передаю их как forward_as_tuple(как тюпл из ссылок).

Но тут пришла печаль аля - "а точно ли нигде не копируется память?".

Стал я думу думать и придумал, что - а вот если бы любое поле(например вектор какой нибудь) можно было бы сделать не копируемым - было бы здорово.

Убер решение:

накидал я ща за 3 секунды

template <typename T>
struct non_copyable : public T
{
  using T::T;
  non_copyable(non_copyable const &) = delete;
  non_copyable & operator=(non_copyable const &) = delete;
};

да и обернул поля

std::vector<int> v1 = { 1,2,3 }; //OK
std::vector<int> v2 = v1; //OK
  
non_copyable<std::vector<int>> ncv1 = { 1,2,3 }; //OK
non_copyable<std::vector<int>> ncv2 = ncv1; //Error

std::vector<int> v3 = ncv1; //OK

Вроде всё работает.

Вопрос в другом:
Нет ли, навскидку, чего готового для такого в бусте, например, или в стд?(хотя в стд похоже точно нет - обещают балалайку на концептах к 20му стандарту)


#1
15:48, 6 дек. 2019

Обычно класс защищают от копирования, а не его поля.

#2
16:04, 6 дек. 2019

njo
> Обычно класс защищают от копирования, а не его поля.

Ясен пень. Но здесь нужно именно поля т.к. они участвуют в сериализации

#3
16:47, 6 дек. 2019

Может все же с архитектурой что-то не то? Чем cereal не подошел? http://uscilab.github.io/cereal/

#4
(Правка: 19:31) 19:30, 6 дек. 2019

njo
> Чем cereal не подошел?

Всё сложно... :)

Там свой транспортный уровень и объекты сериализуются вообще без выделения памяти прямо в шаред мемори, причем поддержаны запросы с динамической памятью, которые  состоят из череды вызовов и опять же все конструляется в шареде - по сути не происходит ни одного - ну или одно копирование, промежуточных буферов нет вообще.  Шареды на лету не создаются, выделения памяти стремятся к 0.
Страшно сложно всё написано - но даёт свой профит

вчера тестил на своей тухлой машине -  гонял списки из 300 строк(в каждой строке по 15 символов)  10000 вызовов (вместе с двумя сериализациями/десериализациями на сервере и клиенте, пробегом по коллекции и пр) ~300мс

коллекция из 2 строк 10000 раз - ~20-30мс

... но и пользоваться этим практически невозможно :) - вот я и нагородил обёртки, чтоб хоть как-то не охренеть, но в тоже время просадить пефеманс нежелательно - сижу борюсь за относительную чистоту...

Сравнивал с красивыми решениями protobuf, flatbuf и проч. и проч уже не помню всех названий - все были позади.

Но к слову эту cereal не тестил - честно не знал про неё, надо посмотреть Спасибо.

#5
23:13, 6 дек. 2019

Всё это синтаксический сахар. Который работает только на уровне анализа кода компилятором.

#6
23:14, 6 дек. 2019

У кланга есть ворнинг на передачу больших структур по значению.
Еще PVS такое проверяет, но ругается даже на мелкие структуры.

#7
2:22, 7 дек. 2019

clang да [-Wlarge-by-value-copy], он и наоборот может найти лишний move [-Wpessimizing-move]

#8
12:38, 7 дек. 2019

Вот тоже про кланг сказать хотел, опередили.
Если стандартный ворнинг не подойдёт, можно под llvm анализатор написать и ручками. Вместе с изучением API должно занять не больше 1 дня.

#9
13:59, 7 дек. 2019

lookid
> Который работает только на уровне анализа кода компилятором.

Дык это и надобно

#!
> clang
блинский у меня gcc и msvc, clang пока не выбран для сборки(не от меня это зависит, хотя конечно от меня, но не только - короче ща не охота билдмашины переделывать ибо смежные отделы подключать - короч гемор), да и в любом случае со студией-то что делать - там тоже надо тестить, а то на одном компиле сработает какой нибудь rvo, на другом не сработает - хз, хочется общего решения, чтоб проверка на уровне языка была, а не компиля.

ПрограммированиеФорумОбщее