Какие идиомы C++ устарели в C++11?



с новым стандартом есть новые способы делать вещи, и многие из них лучше, чем старые способы, но старый способ все еще прекрасен. Также ясно, что новый стандарт официально не очень устарел по причинам обратной совместимости. Так что вопрос остается:



какие старые способы кодирования определенно уступают стилям C++11, и что мы теперь можем сделать вместо этого?



отвечая на это, вы можете пропустить такие очевидные вещи как "авто переменные параметры."

806   9  

9 ответов:

  1. Заключительный Класс: C++11 предоставляет final спецификатор для предотвращения вывода класса
  2. C++11 лямбды существенно уменьшают потребность в именованных классах объектов функций (функторов).
  3. Переместить Конструктор: магические способы std::auto_ptr работы больше не нужны из-за первоклассной поддержки ссылок rvalue.
  4. Safe bool: это было сказано ранее. Явные операторы C++11 устраните эту очень распространенную идиому C++03.
  5. Shrink-to-fit: многие контейнеры C++11 STL обеспечивают shrink_to_fit() функция-член, которая должна устранить необходимость замены с временным.
  6. Временный Базовый Класс: некоторые старые библиотеки C++ используют эту довольно сложную идиому. С семантикой перемещения это больше не нужно.
  7. Введите Безопасное Перечисление перечисления очень безопасны в C++11.
  8. запрещающие выделение кучи: The = delete синтаксис-это гораздо более прямой способ сказать, что определенная функциональность явно запрещена. Это применимо для предотвращения выделения кучи (т. е. =delete для ), предотвращение копирования, присвоения и т. д.
  9. templated typedef:шаблоны псевдоним в C++11 уменьшите потребность в простых шаблонных типах. Однако генераторы сложных типов по-прежнему нуждаются в мета-функциях.
  10. некоторые численные вычисления времени компиляции, такие как Фибоначчи, могут быть легко заменены с помощью обобщенные константные выражения
  11. result_of: Использование шаблона класса result_of следует заменить на decltype. Я думаю result_of использует decltype когда он доступен.
  12. инициализаторы членов класса сохранить ввод для инициализации по умолчанию нестатических элементов со значениями по умолчанию.
  13. в новом коде C++11 NULL должно быть определение nullptr но вижу стл поговорим чтобы узнать, почему они решили с ним.
  14. Шаблон Выражения фанатики рады трейлинг-тип возвращаемого синтаксис функции в C++11. Не более 30-строчных типов возврата!

я думаю, что остановлюсь на этом!

в какой-то момент времени утверждалось, что нужно вернуться const значение вместо просто по значению:

const A foo();
^^^^^

это было в основном безвредно в C++98/03, и, возможно, даже поймали несколько ошибок, которые выглядели так:

foo() = a;

но, возвращаясь к const противопоказан в C++11, потому что он мешает двигаться семантики:

A a = foo();  // foo will copy into a instead of move into it

так что просто расслабьтесь и код:

A foo();  // return by non-const value

как только вы можете отказаться 0 и NULL в пользу nullptr, это делать!

в неуниверсальный код использования 0 или NULL не такое уж и большое дело. Но как только вы начинаете передавать константы нулевого указателя в общем коде, ситуация быстро меняется. Когда вы проходите 0 до template<class T> func(T)T выводится как int и не как константа нулевого указателя. И после этого он не может быть преобразован обратно в константу нулевого указателя. Это каскады в трясина проблем, которые просто не существуют, если Вселенная используется только nullptr.

C++11 не осуждает 0 и NULL как константы нулевого указателя. Но вы должны кодировать, как если бы это было так.

Safe bool idiomexplicit operator bool().

частные конструкторы копирования (boost::noncopyable) → X(const X&) = delete

моделирование конечного класса с частным деструктором и виртуальным наследованиемclass X final

одна из вещей, которые просто заставляют вас избегать написания основных алгоритмов в C++11, - это доступность лямбд в сочетании с алгоритмами, предоставляемыми стандартной библиотекой.

Я использую их сейчас, и невероятно, как часто вы просто говорите, что хотите сделать, используя count_if (), for_each() или другие алгоритмы вместо того, чтобы снова писать проклятые циклы.

Как только вы используете компилятор C++11 с полной стандартной библиотекой C++11, у вас есть нет хорошего оправдания больше не использовать стандартные алгоритмы для построения вашего. Лямбда просто убей его.

Почему?

на практике (после того, как я сам использовал этот способ написания алгоритмов) гораздо легче читать то, что построено с прямыми словами, означающими то, что сделано, чем с некоторыми циклами, которые вам нужно расшифровать, чтобы узнать смысл. Тем не менее, автоматическое выведение лямбда-аргументов поможет сделать синтаксис более легко сопоставимым с a сырая петля.

в принципе, алгоритмы чтения, выполненные со стандартными алгоритмами, намного проще, поскольку слова скрывают детали реализации циклов.

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

вам нужно будет реализовать пользовательские версии swap реже. В C++03, эффективный не бросать swap часто необходимо избегать дорогостоящих и бросающих копий, а так как std::swap использует двух экземплярах, swap часто должен быть настроен. В C++, std::swap использует move, и поэтому фокус смещается на реализацию эффективных и не бросающих конструкторов перемещения и операторов присваивания перемещения. Поскольку для них по умолчанию часто просто отлично, это будет гораздо меньше работы, чем в C++03.

как правило, трудно предсказать, какие идиомы будут использоваться, так как они создаются через опыт. Мы можем ожидать "эффективного C++11", возможно, в следующем году, а" стандарты кодирования C++11 " только через три года, потому что необходимого опыта еще нет.

Я не знаю названия для него, но код C++03 часто использовал следующую конструкцию в качестве замены отсутствующего назначения перемещения:

std::map<Big, Bigger> createBigMap(); // returns by value

void example ()
{
  std::map<Big, Bigger> map;

  // ... some code using map

  createBigMap().swap(map);  // cheap swap
}

Это позволило избежать копирования из-за копирования elision в сочетании с swap выше.

возврат по значению больше не является проблемой. С семантикой перемещения и / или оптимизацией возвращаемого значения(зависящей от компилятора) функции кодирования более естественны без накладных расходов или затрат(большую часть времени).

когда я заметил, что компилятор, использующий стандарт C++11, больше не ошибается в следующем коде:

std::vector<std::vector<int>> a;

для якобы содержащего оператора>>, я начал танцевать. В более ранних версиях нужно было бы сделать

std::vector<std::vector<int> > a;

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

Я, однако, не знаю, было ли это "очевидно" для вас.

Comments

    Ничего не найдено.