TB>У двусвязного списка все плохо с кешем. TB>Кстати а зачем он нужен? Я не моги припомнить таких случаев.
Вообще именно список — для быстрого удаления/добавления в середине.
Двухсвязный — для итерации в оба направления при поиске элемента.
На удивление, не столь бесполезны как кажется — на них lock-less контейнеры чудят.
Здравствуйте, so5team, Вы писали:
S>Исключения могут летать в методах класса-контейнера при добавлении нового элемента.
тут надо говорить предметно. Лично я всегда перестрахуюсь. Потому как завтра придёт новый человек, подумает почему здесь так всё навёрнуто и совсем упустит момент, что это всё ради exception safety.
S>Заключение указателя в optional в C++ общем случае бессмысленно, т.к. этот указатель и есть optional.
ну вот не согласен. Можно сделать метод Person* find() или std::optional<Person*> find(). Во втором обратиться по нулевому указателю намного тяжелее, сложнее на лету вызвать метод find()->name() и т д. В общем, при использовании намного тяжелее не обработать ошибку.
SP>>как то что не поддерживает ссылки S>Так ведь это вопрос, по которому консенсуса не смогли найти
что там за консенсус?
SP>>operator->() может приводить к UB S>А вот это как раз понятно.
а вот мне не понятно. Если заботиться о скорости и забить на безопасность, то optional не нужен от слова совсем. Если важна именно безопасность использования, то хотя бы UB уберите из API.
В целом, складывается ощущение что в C++ optional просто не лезет по целой гамме причин. И зачем такого уродца родил коммитет, совсем не ясно. Лучше взять было стороннюю библиотеку, которая тебя полностью удовлетворяет. А сейчас даже сторонню тяжело взять. Любой на ревью спросит: "да зачем, в стандарте же есть".
Здравствуйте, sergii.p, Вы писали:
S>>Исключения могут летать в методах класса-контейнера при добавлении нового элемента.
SP>тут надо говорить предметно.
Так я вроде и говорю предметно, как человек, которому довелось на коленке пару-тройку подобных примитивных контейнеров слабать.
SP>Лично я всегда перестрахуюсь. Потому как завтра придёт новый человек, подумает почему здесь так всё навёрнуто и совсем упустит момент, что это всё ради exception safety.
Но ведь может прийти человек, который спросит, а зачем мы в C++ тратим ресурсы на то, что должно решаться другими способами? Как бы C++ никогда не был языком, дружественным для новичков. А после взлета Java, C# и Go ему и нет смысла таким оставаться. Это сейчас инструмент для решения задач, для которых пока(?) Java/C#/Scala/Kotlin/F#/Go и пр. не добрались. Поэтому разбрасываться тактами на ровном месте в C++ сейчас не очень понятная идея.
S>>Заключение указателя в optional в C++ общем случае бессмысленно, т.к. этот указатель и есть optional.
SP>ну вот не согласен. Можно сделать метод Person* find() или std::optional<Person*> find(). Во втором обратиться по нулевому указателю намного тяжелее, сложнее на лету вызвать метод find()->name() и т д. В общем, при использовании намного тяжелее не обработать ошибку.
Во втором случае точно так же можно без проблем вызвать find()->name() без предварительных проверок. Т.е. в обоих случаях правильный сценарий использования должен быть таким:
if(auto r = find(); r) {
r->name();
}
И, что характерно, этот код одинаков и для голого указателя, и для optional.
SP>>>как то что не поддерживает ссылки S>>Так ведь это вопрос, по которому консенсуса не смогли найти
SP>что там за консенсус?
Вроде бы вот здесь этот вопрос обсуждался: https://www.fluentcpp.com/2018/10/05/pros-cons-optional-references/
SP>>>operator->() может приводить к UB S>>А вот это как раз понятно.
SP>а вот мне не понятно. Если заботиться о скорости и забить на безопасность, то optional не нужен от слова совсем. Если важна именно безопасность использования, то хотя бы UB уберите из API.
S>Вроде очевидно, что тип с префикосм "unique" не должен так использоваться
Да ладно вам. Накинулись на человека. Как раз здесь Шмыж, как ни странно, прав.
Не редко бывают случаи, когда кто-то создает объект, а затем передает ответственность за этот объект кому-то еще. Как раз с помощью std::unique_ptr. Что-то вроде:
void ensure_valid(const Transaction & trx);
void log_acceptance(const Transaction & trx);
void push_to_processing(std::unique_ptr<Transaction> trx);
...
while(!stop) {
std::unique_ptr<Transaction> trx = acquire_new_trx();
ensure_valid(*trx); // Не отдаем владение.
log_acceptance(*trx); // Не отдаем владение.
push_to_processing(std::move(trx)); // Отдали владение и забыли про объект.
}
Так что наличие std::unique_ptr<T> как аргумент по значению однозначно указывает на то, что вызываемая функция забирает и объект, и ответственность за его дальнейшую судьбу себе.
Здравствуйте, so5team, Вы писали:
S>Как раз здесь Шмыж, как ни странно, прав.
к сожалению он не так уж редко говорит правильные вещи, но из-за сложившейся репутации эти идеи сразу записывают в маргинальные
По-моему идиому, что конструктор принимает строку по значению, высказывал ещё Майерс, только появилась семантика перемещения. А ведь строка — это и есть по сути unique_ptr.
Здравствуйте, Shmj, Вы писали:
S>... S>Компилятор С++ это принимает и не пикнет — максимум варнинг выдаст, и то не всегда. А ведь это 100% ошибка без вариантов. А в Rust право владения — суть концепция самого языка.
C++ даёт возможность расстреливать ноги огромным количеством способов, а Rust — не даёт. Вот это новость!
Здравствуйте, so5team, Вы писали:
S>void push_to_processing(std::unique_ptr<Transaction> trx); S>Так что наличие std::unique_ptr<T> как аргумент по значению однозначно указывает на то, что вызываемая функция забирает и объект, и ответственность за его дальнейшую судьбу себе.
Core Guide говорит использовать такой подход, но есть ли тут гарантия совместимости если push_to_processing это функция из библиотеки которая собранна другой версией компилятора?
Нашел у себя такой код завязянный на Qt:
auto data = std::unique_ptr<QSurfaceDataArray>(new QSurfaceDataArray);
...
// series takes ownership
m_powerSeries->dataProxy()->resetArray(data.release());
Думаю, что resetArray принимает владение через голый указатель именно для гарантии бинарной соместимости.
Здравствуйте, Skorodum, Вы писали:
S>>void push_to_processing(std::unique_ptr<Transaction> trx); S>>Так что наличие std::unique_ptr<T> как аргумент по значению однозначно указывает на то, что вызываемая функция забирает и объект, и ответственность за его дальнейшую судьбу себе. S>Core Guide говорит использовать такой подход, но есть ли тут гарантия совместимости если push_to_processing это функция из библиотеки которая собранна другой версией компилятора?
Если заботиться о разных версиях компилятора и stdlib, то передача вообще чего-либо C++ного по значению, имхо, становится проблемой (да и не по значению тоже стрёмно). И в проектах, где на это заморачиваются, выставляют наружу обычный plain C интерфейс, afaik.
Здравствуйте, Shmj, Вы писали:
S>И придумал для таких же как я простой и наглядный пример
Ты палатой ошибся. Здесь уже вылеченные от "прыжков по языкам" люди. А ты всё как Рогозин, пытаешься улететь в космос на батуте. К чему ты заводишь свои тухлые топики с Растом? У тебя что, чесотка? Успокойся, ПИШИ НА РАСТ, зачем ты людей дёргаешь? Или ты нутром всё же понимаешь, что ковыряешься в говне, но пытаешься выглядеть выше даже C#-щиков?
Здравствуйте, Baiker, Вы писали:
B>Ты палатой ошибся. Здесь уже вылеченные от "прыжков по языкам" люди. А ты всё как Рогозин, пытаешься улететь в космос на батуте. К чему ты заводишь свои тухлые топики с Растом? У тебя что, чесотка? Успокойся, ПИШИ НА РАСТ, зачем ты людей дёргаешь? Или ты нутром всё же понимаешь, что ковыряешься в говне, но пытаешься выглядеть выше даже C#-щиков?
Так как бы не очень хочется, но объективно вынужден признать что парадигмы более строгие.
Здравствуйте, sergii.p, Вы писали:
SP>ну банально чтобы не получить утечку памяти. Ручное удаление может не так уж плохо в С, а в С++ летают исключения — RAII скорей не роскошь, а необходимость.
Ты правда хочешь кидать исключения из деструктора?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Не подскажите, как можно в си++ написать функцию которая считывает и возвращает строку, вызывается в майн и печатается на экране.
Дело в том что я написал ее на раст, а вот на зиг который требует для этого управлением памятью, падает в рантайм с ошибкой утечки памяти.
На раст это оказалось сделать несложно относительно зига, конечно.
Здравствуйте, Разраб, Вы писали:
Р>Не подскажите, как можно в си++ написать функцию которая считывает и возвращает строку, вызывается в майн и печатается на экране. Р>Дело в том что я написал ее на раст, а вот на зиг который требует для этого управлением памятью, падает в рантайм с ошибкой утечки памяти. Р>На раст это оказалось сделать несложно относительно зига, конечно.
Откройте для себя GPT.
C++
#include <iostream>
#include <string>
// Функция для считывания строки с клавиатуры
std::string readStringFromInput() {
std::string inputString;
std::cout << "Введите строку: ";
std::getline(std::cin, inputString);
return inputString;
}
int main() {
// Вызываем функцию для считывания строки
std::string str = readStringFromInput();
// Выводим считанную строку на экран
std::cout << "Вы ввели строку: " << str << std::endl;
return 0;
}
Rust:
use std::io;
// Функция для считывания строки с клавиатурыfn read_string_from_input() -> String {
let mut input_string = String::new();
println!("Введите строку:");
io::stdin().read_line(&mut input_string).expect("Ошибка при считывании строки");
input_string
}
fn main() {
// Вызываем функцию для считывания строкиlet str = read_string_from_input();
// Выводим считанную строку на экран
println!("Вы ввели строку: {}", str);
}
Здравствуйте, CreatorCray, Вы писали:
CC>Ты правда хочешь кидать исключения из деструктора?
не вижу связи. По вашему получается, если человек использует умные указатели, то он хочет кидать исключения из деструктора? Я просто хотел сказать, что в С++ умные указатели более востребованы из-за непредсказуемой последовательности действий. В С мы можем быть точно уверены, что дойдём до конца функции и вызовем очистку памяти, а в С++ любое исключение вносит долю неопределённости.
Здравствуйте, Khimik, Вы писали: K>Ой, сорри. Я попросил GPT3 перевести код на Delphi, сильно понятнее не стало. Тут что-то с умными указателями? В строке void fun1(std::unique_ptr<Class1> smart_ptr){} на входе функции fun1 подаётся два параметра или один?
Тут основная шутка в том что это написал человек не понимающий ассемблера или же просто очень острый шутник. На самом деле std move ничего не перемещает. Объект остается на стеке или в регистрах и спокойно переиспользуетмя. Формально там ошибка (нуачо, объект же был перемещен) по факту нет
B>Ты палатой ошибся. Здесь уже вылеченные от "прыжков по языкам" люди. А ты всё как Рогозин, пытаешься улететь в космос на батуте. К чему ты заводишь свои тухлые топики с Растом? У тебя что, чесотка? Успокойся, ПИШИ НА РАСТ, зачем ты людей дёргаешь? Или ты нутром всё же понимаешь, что ковыряешься в говне, но пытаешься выглядеть выше даже C#-щиков?