Comments 23
Срочно читать Когда писать std::endl а когда '\n'? и "std::endl" vs "\n".
std::vector— это специализация шаблонаstd::vector
Вектор - это специализация шаблона вектора. Что?
Привет.
Нагадил вам в карму, потому что вторая статья от вас - полностью сгенерированная нсетью. На хабре много статей "подправленных" ллм, но с авторским содержанием, у вас же ни одной своей мысли там не видно.
Прекращайте это дело.
пс: сгенерированным "спасибо" не надо отвечать, уже тошнит видеть это дмо кругом.
Спасибо за комментарий, за Ваше оценочное суждение, за советы, которые у Вас не спрашивали, за Ваши утверждения, но не за тактичность и не за вопросы, которых у Вас нет. У меня же к Вам единственный вопрос - статья была полезной?
Здесь тоже торчат уши ллм.
Вы можете своими словами отвечать? Вам уже 45 лет. Неужели вы не можете сфорулировать пару слов самостоятельно.
Статья ваша - это памятка, ничего нового, все это было прочитано давно уже и руками набрано не раз.
Непрошенный совет вам еще - пишите сами, пока есть такая возможность, пока мозги не отсохли еще.
Всегда ли для Вас грамотная речь ассоциируется с "ллм"? Статья отмечена как обзор, и, с моей точки зрения она в полном объеме выполняет свое предназначение. И, надеюсь, позволит значительно уменьшить количество ошибок, допускаемых как начинающими, так и опытными разработчиками. Если у Вас есть ссылка на другие, более качественные источники по данной тематике, и Вы ими поделитесь, буду очень рад.
Очень жаль, что за свои 40 лет Вы не научились конструктивно вести диалог и критиковать, но, уверяю Вас, еще не поздно начать эволюционировать. Откровенно говоря, не хочется даже думать, каким образом Вы проводите code-review, надеюсь не таким же, как Вы ведете данную переписку, а все-таки соблюдаете какие-то общепринятые нормы и этикет, рекомендую обратиться к словарю, чтобы понять значение данного слова. Также, к сожалению, по опыту знаю, что человек, утверждающий, что все знает, как правило, мягко говоря, не совсем компетентен. Считаю неправильным переходить на личности, но раз уж Вы себе позволили...
Рад, что стали говорить как надо было сразу.
Вот вам для примера статья соседняя (по времени выхода имею ввиду) с вашей
https://habr.com/ru/articles/964282/
Почитайте и увидите разницу, и поймете мбыть, что значит своими словами написано.
В сообщении указывалось "на другие, более качественные источники по данной тематике", Вы же привели пример статьи по матанализу. К сожалению, Вы или пропустили, или проигнорировали этот существенный момент. Смысл сообщения заключался в том, чтобы читателям, которым не удобен формат данной статьи, была доступна альтернативная статья, написанная более понятным простым языком. Хочется, чтобы данный спор принес все-таки определенную пользу.
Если у вас есть конструктор перемещения, то конструктор копирования не будет создаваться автоматически.
Гарантии безопасности исключений
std::vectorпредоставляет строгую гарантию (strong exception guarantee) для большинства операций:
Если операция бросает исключение, вектор остается в исходном состоянии
НО: только если конструктор перемещения
Tпомеченnoexcept!
Ну это уже совсем бред. Буквально несколько абзацев назад было написано, что вектор при реаллокации может копировать или перемещать элементы в зависимости от noexcept'ности конструктора перемещения хранимого типа. Спойлер - это сделано именно для того чтобы обеспечить strong exception safety guarantee для типов, у которых move-constructor не noexcept. (Там есть несколько нюансов про типы, которые не CopyInsertable, но это совсем частные случаи. Кстати, было бы круто, если бы эти нюансы упомянули в статье под названием "std::vector: от основ до тонкостей реализации").
Соответственно, в приведенном примере вообще не будет вызываться перемещающий конструктор. так что с вектором все будет нормально.
struct ThrowingType {
ThrowingType() = default;
ThrowingType(const ThrowingType&) = default;
// ❌ Может бросить исключение
ThrowingType(ThrowingType&&) {
throw std::runtime_error("Move failed!");
}
};
std::vector<ThrowingType> v(10);
try {
v.reserve(20); // может привести к неконсистентному состоянию!
} catch (...) {
// v может быть поврежден
}Пример кода действительно вводит в заблуждение, уточнение с НО будет справедливо только при условии, когда в приведенном коде = default будет заменен на = delete или же класс будет содержать только перемещаемое поле. Общий подход следующий - производится попытка использовать конструктор перемещения, если он noexcept, иначе производится попытка использовать конструктор копирования, если же и это невозможно, то остается только вызов небезопасного перемещающего конструктора. Также рекомендую комментатору придерживаться этических норм, это сделает обсуждение более продуктивным.
Рекомендую автору перестать копировать ответы из llm и проверять статьи перед публикацией на предмет корректности содержимого.
Уважаемый комментатор, могу только посоветовать Вам обратиться к моему ответу Tyiler. Следуя Вашей логике вся деловая переписка и / или техническая литература является плодом усилий llm. Возможно, Вам необходимо несколько повысить свой уровень грамотности, чтобы Вам не мерещились в каждом сообщении llm. Очень жаль, что обсуждение статьи превратилось в балаган, или, говоря Вашим языком - срач.
Такие статьи надо сразу удалять не разбирая, там куча ошибок, новичку это читать прямо противопоказано
Есть момент, ради которого я пролистал всю статью до конца (я не буду давать комментарии относительно ИИ - какая разница, главное суть). А момент этот, собственно- реальное сравнение производительности для подкрепления сведений. Увы, это основное, чего в статье нет.
push_backсоздает объект, затем перемещает/копирует его в вектор
emplace_backсоздает объект прямо в векторе (без копирования/перемещения)
push_back сам по себе ничего не создает. Пример из статьи корректен, но лишний вызов конструктора происходит на стороне, вызывающей push_back.
std::vector<Point> v;v.reserve(10);// чтобы избежать реаллокаций// push_back: конструктор + movev.push_back(Point(1, 2));// Вывод:// Constructor// Move constructor// emplace_back: только конструкторv.emplace_back(3, 4);// Вывод:// Constructor
Для уже существующих объектов разницы не будет
std::vector<Something> v;
Something v1, v2;
v.push_back(v1); // copy
v.push_back(std::move(v1)); // move
v.emplace_back(v2); // copy
v.emplace_back(std::move(v2)); // move-------------------------------
Что возвращают:
push_back:void(до C++17),reference(C++17+)
emplace_back:void(до C++17),reference(C++17+)
push_back не возвращает reference.
reserve(): предварительное выделение памяти
Когда НЕ использовать:
❌ Работаете с огромными объектами и хотите экономить память
Не очень ясно, как неиспользование reserve поможет экономить память, учитывая экспоненциальную стратегию роста при использовании push_back/emplace_back.
-------------------------------
1. Избегайте ненужных копирований
// ❌ Плохо: копирование при каждой вставке
std::vector<std::string> v;
for (const auto& s : data) {
v.push_back(s); // копирование
}
// ✅ Хорошо: перемещение
std::vector<std::string> v;
for (auto&& s : data) {
v.push_back(std::move(s)); // перемещение
}
// ✅ Еще лучше: emplace_back (если подходит)
std::vector<std::string> v;
for (const auto& s : data) {
v.emplace_back(s);
}Тут на самом деле нет разницы между первым и последним примером - и там и там копирование всего вектора.
Чудный новый мир, где статьи пишут боты и отвечают на комментарии тоже
хорошая статья, особенно ссылки на буст аналоги. пишите еще про буст аналоги для других котейнеров.
Как данная статья вообще до сих пор существует... У "автора" llm при генерации текста запуталась в мыслях, от чего куча противоречий. Новичкам данное "чтиво" противопоказано.
Человек, генерирующий статьи и даже, только задумайтесь, ответы в комментариях... На лицо запущенная зависимость от llm.
std::vector: от основ до тонкостей реализации