Re[5]: COW устарел, осторожнее с его использованием?
От: vopl Россия  
Дата: 26.08.22 08:30
Оценка:
Здравствуйте, pax123, Вы писали:

P>А нельзя для неконстантного operator[] возвращать прокси объект, который имеет оператор преобразования и оператор присваивания, и только в последнем производить расщепление строки?


Нельзя, это явный слом существующего API, что не допустимо.
Re[5]: COW устарел, осторожнее с его использованием?
От: sergii.p  
Дата: 26.08.22 09:52
Оценка: +1
Здравствуйте, pax123, Вы писали:

АТ>>
АТ>>std::string a = "abc";
АТ>>const char *ptr = a.data();

АТ>>{
АТ>>  std::string b = a;
АТ>>  a[0];
АТ>>}

АТ>>// ...
АТ>>


P>А нельзя для неконстантного operator[] возвращать прокси объект, который имеет оператор преобразования и оператор присваивания, и только в последнем производить расщепление строки?


вроде без разницы. Ну будет
a[0] = 'A';

всё равно ведь ptr висит
Re[6]: COW устарел, осторожнее с его использованием?
От: pax123  
Дата: 26.08.22 12:14
Оценка:
Здравствуйте, vopl, Вы писали:

P>>А нельзя для неконстантного operator[] возвращать прокси объект, который имеет оператор преобразования и оператор присваивания, и только в последнем производить расщепление строки?


V>Нельзя, это явный слом существующего API, что не допустимо.


А что именно сломается?
Re[5]: COW устарел, осторожнее с его использованием?
От: qaz77  
Дата: 26.08.22 12:20
Оценка:
Здравствуйте, pax123, Вы писали:
P>А нельзя для неконстантного operator[] возвращать прокси объект, который имеет оператор преобразования и оператор присваивания, и только в последнем производить расщепление строки?

В старой книжке по C++03, то ли Мейерса, то ли Саттера, разбирался такой пример с char прокси для строки.
Re[7]: COW устарел, осторожнее с его использованием?
От: vopl Россия  
Дата: 26.08.22 13:48
Оценка:
Здравствуйте, pax123, Вы писали:

P>Здравствуйте, vopl, Вы писали:


P>>>А нельзя для неконстантного operator[] возвращать прокси объект, который имеет оператор преобразования и оператор присваивания, и только в последнем производить расщепление строки?


V>>Нельзя, это явный слом существующего API, что не допустимо.


P>А что именно сломается?


Сломаются прикладные варианты использования этого std::string::operator[]. Другими словами — вся прикладная кодовая база, которая завязана на специфику текущего API — она перестанет работать. А на эту специфику завязано много кода..

Например, предлагаемый прокси не будет прямо или косвенно предоставлять информацию об адресе проксируемого символа (хотя бы потому что такой адрес в случае прокси теряет смысл). Но, существует немало кода, так или иначе завязанного на то что operator[] такой адрес (косвенно) предоставляет:
std::string s = "...";
char* begin = &s[0];
char* end = s.data() + s.size();
assert(end - begin == s.size());


вот такое легаси будет сломано
Re[8]: COW устарел, осторожнее с его использованием?
От: pax123  
Дата: 26.08.22 14:00
Оценка:
Здравствуйте, vopl, Вы писали:

V>Например, предлагаемый прокси не будет прямо или косвенно предоставлять информацию об адресе проксируемого символа (хотя бы потому что такой адрес в случае прокси теряет смысл). Но, существует немало кода, так или иначе завязанного на то что operator[] такой адрес (косвенно) предоставляет:


Почему не будет?

Object* operator&(Object&& object) { return std::addressof(object); }
Re[9]: COW устарел, осторожнее с его использованием?
От: vopl Россия  
Дата: 26.08.22 14:09
Оценка:
Здравствуйте, pax123, Вы писали:

P>Здравствуйте, vopl, Вы писали:


V>>Например, предлагаемый прокси не будет прямо или косвенно предоставлять информацию об адресе проксируемого символа (хотя бы потому что такой адрес в случае прокси теряет смысл). Но, существует немало кода, так или иначе завязанного на то что operator[] такой адрес (косвенно) предоставляет:


P>Почему не будет?


P>
P>Object* operator&(Object&& object) { return std::addressof(object); }
P>


Не вполне понял, что за адрес будет возвращен? Кто такой Object object?
Re[10]: COW устарел, осторожнее с его использованием?
От: watchmaker  
Дата: 26.08.22 14:46
Оценка: 9 (1)
Здравствуйте, vopl, Вы писали:


P>>
P>>Object* operator&(Object&& object) { return std::addressof(object); }
P>>


> Кто такой Object object?

Это не важно. Сниппет демонстрирует, что в С++ можно перегружать унарный operator&.


V>Не вполне понял, что за адрес будет возвращен?

С помощью перегрузки my_char_proxy::operator& ты можешь сделать, что &t[0] будет возвращать не адрес прокси-объекта, а адрес символа в строке. А так как можно делать разные перегрузки для const/не-const, то в случае константных строк адрес может указывать в общий буфер. А в случае модификации *&s[0] = 'a' перегрузка сначала склонировует строку и вернёт адрес, в который можно безопасно писать без риска испортить общую память. Классический copy-on-write.

Вот пример реальной реализации такого proxy-объекта для cow-строк: catboost/string.h.
Re[11]: COW устарел, осторожнее с его использованием?
От: vopl Россия  
Дата: 26.08.22 15:01
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, vopl, Вы писали:



P>>>
P>>>Object* operator&(Object&& object) { return std::addressof(object); }
P>>>


>> Кто такой Object object?

W>Это не важно. Сниппет демонстрирует, что в С++ можно перегружать унарный operator&.


V>>Не вполне понял, что за адрес будет возвращен?

W>С помощью перегрузки my_char_proxy::operator& ты можешь сделать, что &t[0] будет возвращать не адрес прокси-объекта, а адрес символа в строке. А так как можно делать разные перегрузки для const/не-const, то в случае константных строк адрес может указывать в общий буфер. А в случае модификации *&s[0] = 'a' перегрузка сначала склонировует строку и вернёт адрес, в который можно безопасно писать без риска испортить общую память. Классический copy-on-write.

W>Вот пример реальной реализации такого proxy-объекта для cow-строк: catboost/string.h.


Ну да, согласен. Хотя не будет правильно работать addressof(str[i]), но это уже придирки..
Re[7]: COW устарел, осторожнее с его использованием?
От: vopl Россия  
Дата: 26.08.22 15:10
Оценка:
Здравствуйте, pax123, Вы писали:

P>Здравствуйте, vopl, Вы писали:


P>>>А нельзя для неконстантного operator[] возвращать прокси объект, который имеет оператор преобразования и оператор присваивания, и только в последнем производить расщепление строки?


V>>Нельзя, это явный слом существующего API, что не допустимо.


P>А что именно сломается?


Еще такое
addressof(str[i]) — выдает не тот тип и не тот адрес
decltype(str[i]) — выдает не тот тип. Чревато это будет в тех местах где результат operator[] подается в перегрузки, в шаблонные штуки всякие и прочие места для которых важен тип именно итогового значения а не его обертки
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.