Pull to refresh
77
0
Матросов Михаил @mmatrosov

User

Send message

auto_ptr уже deprecated. Зачем вы его используете для тестов?

100% совместимость может быть только со 100% неизменяемым язком. На любое изменение всегда можно придумать код, который будет этим изменением сломан

Здесь вы расширение языка не называете изменением?

Сделайте using namespace на уровне данной функции или вообще на уровне блока. Вызванные потенциальные проблемы будут минимальны.

Да, вы, разумеется, правы, этот момент я отметил в статье. Здесь я рассуждал так: человек задаёт вопрос, почему нельзя использовать std::array вместо std::vector => он упустил некоторые основы => делать подобные уточнения смысла нет, надо кратко отметить, в чём разница, чтобы было понятно.

здесь выполняется проверка что в reset не передали тот же самый указатель

Каким образом, если сравнение идёт с нулевым указателем? Собственно, на cppreference указано:


A test for self-reset, i.e. whether ptr points to an object already managed by *this, is not performed, except where provided as a compiler extension or as a debugging assert.
Во втором случае мы сами управляем памятью, поэтому можно использовать std::unique_ptr:

Согласен, выглядит разумно.


Чем unowned_ptr лучше «сырого» указателя? Тем, что у него информация о владении закреплена в типе. Никому в голову не придёт его удалить.
Bjarne уже несколько лет толкает идею unowned_ptr в C++. Прямо сейчас он, наряду с другими полезными мелочами, лежит в Guidelines Support Library.

Тут вы немного перепутали. В C++ Core Guidelines и в GSL реализован обратный вариант — владеющий указатель owner<T>. Сырой указатель T* считается невладеющим. Об этом Саттер и Страуструп как раз и рассказывали в своих выступлениях (кажется, на GoingNative 2015, могу поискать, если нужно).


По поводу MakeQObject. Там фундаментальная проблема в том, что в Qt, как я понимаю, есть мода разделять создание объектов и их прицепление к родителю. Т.к. исключений там нет, это считается безопасным. Насколько такая аргументация убедительно — сказать не могу, опыт работы с Qt у меня небольшой.


В любом случае, я всячески приветствую предложить ваши идеи в тот же самый список рассылки :)

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

Вопрос терминологии. Мне казалось логичным, что «современным» называют язык, который стандартизован и поддерживается рядом мажорных компиляторов.

Даже если кто-то что-то и сказал в прошлом, не надо считать это догмой вне зависимости от контекста и предметной области

Я не хотел называть это догмами. Без фанатизма. Да, С++ отличается широким применением и, как следствие, сильно варьируется для разных контекстов и предметных областей. Однако, можно выделить некоторые общие рекомендации, которые работают в большинстве случаев. Например, с мажорными компиляторами. Такие рекомендации вполне можно считать умолчаниями. Если в конкретном контексте или области они неприменимы — без проблем. Просто нужно понимать, почему они не применимы. Возможно, в связи со спецификой конкретного компилятора или платформы (например, не реализованы определённые оптимизации, не поддерживаются определённые инструменты). Возможно, в связи со спецификой предметной области (например, жёсткое ограничение на время отклика системы, которое требует абсолютной прозрачности потока выполнения). Но умолчания это не меняет.

Не пугайтесь и не пугайте юниоров использовать new() в коде: a.reset(new A());

В качестве исключения — до, конечно, можно. По умолчанию — нет. И в статье описано, почему.
Хорошее замечание, спасибо. Такая проблема есть, универсального решения нет. Больше информации по ссылкам:
http://stackoverflow.com/q/25330716/261217
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf
std::make_unique появился только в c++14

В статье говорится о современном С++. Современный С++ на данный момент и есть С++14.

std::shared_ptr::reset() и std::unique_ptr::reset() созданы для использования с оператором new()

Если быть более точным, они созданы для работы с владеющими указателями. Оператор new — один из способов такой указатель создать. Так или иначе, если в С++ есть инструмент Х, это не значит, что им нужно обязательно пользоваться. В С++ вообще такая философия, что давайте сначала накидаем инструментов, а потом посмотрим, как оно полетит. Наберёмся опыта и выработаем гайдлайны, как этим на самом деле нужно пользоваться. Вот можно ловить исключения по значению, но так делать не надо, потому как слайсинг, исключение при копировании исключения и всё такое. Можно вернуть из функции константный объект по значению, но это не имеет смысла и может скорее только навредить. Можно сделать виртуальную функцию шаблонной или добавить её аргументам значения по умолчанию, но проблем не оберёшься потом. Можно объявить неконстистентные операторы сравнения, но тогда их уже нельзя будет назвать операторами сравнения. Примеров можно много набрать. Поэтому сейчас и развиваются C++ Core Guidelines. Убрать какой-то инструментарий из языка мы не можем — обратная совместимость дело святое. Остаётся оградить разработчиков от неразумного использования существующего инструментария. Именно от неразумного. Т.к. под каждый пример при желании можно подобрать специфическую ситуацию, где следует отойти от гайдлайнов. Но это другой разговор. Это особенные случаи. И в статье я указал на факт, что в особенных ситуациях без использования new и delete нам не обойтись.

Даже если кто-то что-то и сказал в прошлом, не надо считать это догмой вне зависимости от контекста и предметной области.

Простите, это вы о чём конкретно?

Не надо пугаться использовать new(), надо пугаться не уметь делать вменяемый дизайн.

Не вижу, как это связано. По-моему, это ортогональные вещи.
Это совершенно разные контейнеры. std::vector — буфер выделяется в куче, размер неизвестен на этапе компиляции. std::array — буфер выделяется на стеке, размер должен быть известен на этапе компиляции.
Visual Studio 2013 поддерживает make_unqiue. Если говорить о Visual Studio, то Visual Studio 2015 Update 2 уже имеет вполне неплохую поддержку С++14. Думаю, имеет смысл смотреть именно на последнию версию в рамках конкретного компилятора.

> надо во все файлы включать один общий хедер
Достаточно часто такие хедеры имеются уже готовые. Какие-нибудь самые базовые, утилитарные. Если есть pch — ещё проще. Но, конечно, всё индивидуально. Только вы сами можете решить, какое решение лучше подходит в вашем случае. Со своей стороны я лишь надеюсь, что смог собрать в одном месте достаточно информации, чтобы можно было взвесить за и против.
Да, верно, такая проблема есть. Если вы вынуждены использовать С++11, следует хотя бы избавиться от delete:
auto* data = new data::Value(std::move(val));
thread.perform([this, data] () -> bool {
  std::unique_ptr<data::Value> dataPtr(data);
  updateFromData(*data);
  return true;
});

Другой вариант — использовать shared_ptr. Во многих случаях вполне себе вариант. Время работы нити обычно несравнимо больше времени копирования shared_ptr.
В С++14, действительно, можно использовать init capture. Оставлю здесь пример для полноты:
auto data = std::make_unique<data::Value>(std::move(val));
thread.perform([this, data = std::move(data)]() -> bool {
  updateFromData(*data);
  return true;
});
Не совсем понимаю, почему вы разделяете С++14 и С++11? По моему опыту, люди либо используют современные компиляторы, где уже есть (почти) полная поддержка С++14, либо застряли в прошлом веке, где и С++11 не пахнет.

Так или иначе, вполне можно без палева подпихнуть в std свою реализацию make_unique (см. http://stackoverflow.com/a/12580468/261217):
namespace std
{
  template<typename T, typename... Args>
  std::unique_ptr<T> make_unique(Args&&... args)
  {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  }
}

Когда компилятор будет наконец обновлён, её нужно будет удалить, а весь код будет работать точно так же. Когда мы в прошлой компании некоторое время застряли на Visual Studio 2010, мы ровно так и поступили.
> Мы создали рабочую группу (РГ21) на основе сотрудников Яндекса, группа является национальной зеркальной рабочей группойISO/IEC JTC1/SC22/WG21 C++.

Не могли бы вы уточнить, что конкретно это значит?
Звучит разумно. Но, казалось бы, ровно этим занимаются тулбары. Ведь риббон по сути и отличается от тулбаров лишь наличием вкладок наверху. Или есть ещё что-то фундаментальное?
но вспомните, например, по какой причине в MS Office появился «ленточный» интерфейс

А была какая-то конкретная причина? Было бы интересно услышать.
В определённых ситуациях — да, статическая линковка может быть оправдана. Но вот «всем рекомендовать» её — достаточно смело, т.к. она обладает рядом недостатков:
1. Размер бинарника. В противовес вашему пункту 3, проблема среднестатистического пользователя решается запросом Visual Studio Redistributable из инсталлятора. Это возможно не всегда, да, исключения я как раз и отношу к «определённым ситуациям». Однако в большинстве случаев это работает отлично, и я обычно встречаю именно такой подход.
2. Размер исполнимого файла и библиотек в памяти. Если CRT слинкован динамически, то на все процессы будет использоваться только одна загруженная из системной области библиотека.
3. Security updates. Windows может обновить системные библиотеки с сохранением ABI, но не сможет достучаться до ваших копий.
4. Передача объектов между модулями. Если вы создали std::string в одной dll и передали его в другую, то при его освобождении будут проблемы, т.к. выделение и уничтожение выполняется разными CRT. Это по сути значит, что вы не можете свободно использовать С++ интерфейсы. Пожалуй, это главная проблема.

Собственно, сам Microsoft не рекомендует статическую линковку.
Интересная деталь работы компоновщика, благодарю.
А зачем её отключать, если не секрет? Вижу несколько возможных причин:
1. Накладные расходы на старте/завершении приложения
2. Увеличение размера исходника при статической линковке CRT (а так кто-то ещё делает?)
3. Паранойя
С другой стороны, отключая телеметрию, мы лишаем ОС некоторой (вроде бы вполне невинной) информации о приложении. И усложняем жизнь коллегам разработчикам. Так что именно побудило вас броситься её отключать?
А не будет ли ошибки при линковке, что символы объявлены дважды?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity