Введение
2011 издание стандарта языка программирования C++ C++11 является версией стандарта ISO/IEC 14882 для языка программирования C++. C++11 заменил предыдущую версию стандарта C++, названную C++03, а позже был заменен на C++14. Название следует традиции названия языковых версий по году публикации спецификации, хотя ранее оно было названо C++0x, потому что ожидалось, что оно будет опубликовано до 2010 года. Хотя одной из целей проектирования было предпочтение изменений в библиотеках перед изменениями в основном языке, C ++ 11 делает несколько дополнений в основной язык. Области основного языка, которые были значительно улучшены, включают поддержку многопоточного программирования, поддержку общего программирования, единообразную инициализацию и производительность. Значительные изменения были также внесены в стандартную библиотеку C ++, включающую большинство библиотек технического отчета C ++ 1 (TR1), за исключением библиотеки математических специальных функций. C++11 был опубликован как ISO/IEC 14882:2011 в сентябре 2011 года и доступен за плату. Рабочий проект, наиболее похожий на опубликованный стандарт C++11, N3337, от 16 января 2012 года; в нем есть только редакционные исправления от стандарта C++11. C++11 полностью поддерживается Clang 3.3 и более поздними версиями. C++11 полностью поддерживается GCC 4.8.1 и более поздними версиями.
C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010. Although one of the design goals was to prefer changes to the libraries over changes to the core language, C++11 does make several additions to the core language. Areas of the core language that were significantly improved include multithreading support, generic programming support, uniform initialization, and performance. Significant changes were also made to the C++ Standard Library, incorporating most of the C++ Technical Report 1 (TR1) libraries, except the library of mathematical special functions. C++11 was published as ISO/IEC 14882:2011 in September 2011 and is available for a fee. The working draft most similar to the published C++11 standard is N3337, dated 16 January 2012; it has only editorial corrections from the C++11 standard. C++11 is fully supported by Clang 3.3 and later. C++11 is fully supported by GCC 4.8.1 and later.
Расширения на основной язык C++
Одной из функций комитета по C++ является разработка ядра языка. Области основного языка, которые были значительно улучшены, включают поддержку многопоточного программирования, поддержку общего программирования, единообразную инициализацию и производительность.
Улучшение производительности на время выполнения основных языков
Эти языковые особенности существуют в первую очередь для обеспечения некоторого вида преимущества производительности, будь то памяти или вычислительной скорости.
Ссылки на R-значения и конструкторы движения
В C++03 (и ранее) временные (называемые "rvalues", поскольку они часто лежат на правой стороне задания) были предназначены для того, чтобы никогда не быть модифицируемыми так же, как в C и считались неотличимыми от const T& типов; тем не менее, в некоторых случаях временные могли быть модифицированы, поведение, которое даже считалось полезной лазейкой. C++11 добавляет новый тип ссылки, не являющийся константой, называемый ссылкой rvalue, идентифицированной T&&. Это относится к временным файлам, которые могут быть изменены после их инициализации, с целью обеспечения "семантики перемещения". Хронической проблемой производительности C++03 являются дорогостоящие и ненужные глубокие копии, которые могут возникать имплицитно, когда объекты передаются по стоимости. Чтобы проиллюстрировать проблему, рассмотрим, что std:: vector<T> является, внутренне, обертыванием вокруг массива стиля C с определенным размером. Если временный std::vector<T> создан или возвращен из функции, он может быть сохранен только путем создания нового std::vector<T> и копирования всех данных rvalue в него. Тогда временное и вся его память уничтожаются. (Для простоты, в этом обсуждении не учитывается оптимизация возвратной стоимости.) В C++11 конструктор движения std::vector<T>, который принимает ссылку rvalue на std::vector<T>, может скопировать указатель на внутренний массив стиля C из rvalue в новый std::vector<T>, а затем установить указатель внутри rvalue на нуль. Поскольку временный код больше никогда не будет использован, ни один код не будет пытаться получить доступ к нулевому указателю, и поскольку указатель является нулевым, его память не удаляется, когда он выходит из зоны действия. Таким образом, операция не только не требует затрат на глубокую копию, но и безопасна и невидима. Ссылки Rvalue могут обеспечить преимущества в производительности существующего кода без необходимости вносить какие-либо изменения за пределами стандартной библиотеки. Тип возвращаемого значения функции, возвращающей std::vector<T> temporary, не должен быть явно изменен на std::vector<T> && для вызова конструктора движения, поскольку временные значения автоматически считаются rvalues. (Однако, если std::vector<T> является версией C++03 без конструктора движения, то конструктор копирования будет вызван с const std::vector<T>&, что влечет за собой значительное распределение памяти.) По соображениям безопасности, некоторые ограничения наложены. Именной переменной никогда не будет считаться rvalue, даже если она объявлена таковой. Для получения rvalue следует использовать шаблон функции std::move. Ссылки на R-значение также могут быть изменены только при определенных обстоятельствах, поскольку они предназначены для использования в основном с конструкторами движения. Из-за характера формулировки ссылок rvalue и некоторых изменений в формулировке ссылок lvalue (обычных ссылок) ссылок rvalue позволяют разработчикам обеспечивать идеальную функцию пересылки. В сочетании с вариативными шаблонами эта возможность позволяет создавать шаблоны функций, которые могут идеально перенаправлять аргументы в другую функцию, которая принимает эти конкретные аргументы. Это наиболее полезно для пересылки параметров конструктора, для создания фабричных функций, которые автоматически вызовут правильный конструктор для этих конкретных аргументов. Это видно в emplace back-набор методов стандартной библиотеки C++.
Улучшение удобства использования основных языков
Эти функции существуют в первую очередь для того, чтобы сделать язык более удобным в использовании. Они могут улучшить безопасность типографии, свести к минимуму повторение кода, уменьшить вероятность ошибочного кода и т. Д.
Операторы прямого преобразования
C++98 добавил явное ключевое слово в качестве модификатора на конструкторах, чтобы предотвратить использование конструкторов с одним аргументом в качестве операторов конверсии имплицитного типа. Однако это не имеет никакого значения для операторов конверсии. Например, класс умных указателей может иметь оператор bool, позволяющий ему действовать больше, чем примитивный указатель: если он включает в себя это преобразование, его можно проверить с помощью if (умная переменная ptr) (которая была бы истинной, если бы указатель был не нулевым и ложным в противном случае). Однако это позволяет и другим, непреднамеренным преобразованиям. Поскольку в C++ bool определяется как арифметический тип, его можно неявно преобразовать в типы интегральных или даже плавающих точек, что позволяет выполнять математические операции, которые не предусмотрены пользователем. В C++11 теперь можно применять эксплицитное ключевое слово к операторам преобразования. Как и в случае с конструкторами, он предотвращает использование этих функций преобразования в имплицитных преобразованиях. Однако языковые контексты, которые конкретно нуждаются в булевом значении (условия if-заказов и циклов, а также операнды к логическим операторам), считаются явными преобразованиями и, таким образом, могут использовать оператор преобразования bool. Например, эта функция чисто решает проблему безопасного була.
Улучшения основных языковых функций
Эти особенности позволяют языку делать то, что раньше было невозможно, чрезвычайно многословно или требовало не переносимых библиотек.
Вариадические шаблоны
В C++11 шаблоны могут принимать переменное количество параметров шаблона. Это также позволяет определить безопасные для типа вариадические функции.
Многопоточная модель памяти
C++11 стандартизирует поддержку многопоточного программирования. В ней участвуют две части: модель памяти, которая позволяет нескольким потокам сосуществовать в программе, и библиотечная поддержка взаимодействия между потоками. (Смотрите раздел этой статьи о проводке.) Модель памяти определяет, когда несколько потоков могут получить доступ к одному и тому же местоположению памяти, и указывает, когда обновления одного потока становятся видимыми для других потоков.
Локальное хранение в потоке
В многопоточной среде, это обычное для каждого потока, чтобы иметь некоторые уникальные переменные. Это уже происходит для локальных переменных функции, но не происходит для глобальных и статических переменных. Новая продолжительность локального хранения потока (в дополнение к существующим статическим, динамическим и автоматическим) указывается в спецификаторе локального хранения потока. Любому объекту, который может иметь статическую продолжительность хранения (то есть срок жизни, охватывающий все выполнение программы), вместо этого может быть присвоена локальная продолжительность потока. Цель состоит в том, что, как и любая другая переменная статической продолжительности, локальный объект потока может быть инициализирован с помощью конструктора и уничтожен с помощью деструктора.
Явно исключенные функции
Функция может быть явно отключена. Это полезно для предотвращения скрытых преобразований типов. Спецификатор = delete может быть использован для запрета вызова функции с определенными типами параметров.
Разрешить реализацию системы сбора мусора
Предыдущие стандарты C++ предусматривали программируемый сбор мусора через set new handler, но не давали определения доступности объекта для автоматического сбора мусора. C++11 определяет условия, при которых значения указателя "безопасно производятся" от других значений. В реализации может быть указано, что она работает в строгом режиме безопасности указателя, в этом случае указатели, которые не получены в соответствии с этими правилами, могут стать недействительными.
Изменения в стандартной библиотеке C++
В стандартной библиотеке C++11 был введен ряд новых функций. Многие из них могли быть реализованы в соответствии со старым стандартом, но некоторые полагаются (в большей или меньшей степени) на новые основные функции C ++ 11. Большая часть новых библиотек была определена в документе C++ Standards Committee's Library Technical Report (называемом TR1), который был опубликован в 2005 году. В настоящее время доступны различные полные и частичные реализации TR1, использующие пространство имен std:: tr1. Для C++11 они были перемещены в пространство имен std. Однако, поскольку функции TR1 были включены в стандартную библиотеку C++11, они были обновлены, где это было уместно, с функциями языка C++11, которые не были доступны в первоначальной версии TR1. Кроме того, они могли быть улучшены с возможностями, которые были возможны в C ++ 03, но не были частью оригинальной спецификации TR1.
Устройства для резьбы
В то время как язык C ++ 03 предоставляет модель памяти, которая поддерживает потоковое взаимодействие, основная поддержка для фактического использования потокового взаимодействия поставляется со стандартной библиотекой C ++ 11. Предоставляется класс потока (std::thread), который принимает объект функции (и дополнительные серии аргументов для передачи ему) для запуска в новом потоке. Можно заставить поток остановиться до тех пор, пока другой выполняющий поток не завершит, обеспечивая поддержку соединения потоков через функцию std::thread::join. Доступ к базовому объекту native thread ((s) для операций, специфичных для платформы, обеспечивается, когда это возможно, с помощью функции std::thread::native handle. Для синхронизации между потоками, соответствующие мутеки (std::mutex, std::recursive mutex и т.д.) и переменные состояния (std:: переменная состояния и std:: переменная состояния любой) добавляются в библиотеку. Они доступны через блокировки RAII (std::lock guard и std::unique lock) и алгоритмы блокировки для удобства использования. Для высокопроизводительной работы на низком уровне иногда требуется связь между потоками без накладных затрат мутекса. Это делается с использованием атомных операций на местах памяти. Они могут дополнительно указывать минимальные ограничения видимости памяти, необходимые для операции. Для этой цели также могут использоваться явные барьеры памяти. Библиотека потоков C++11 также включает в себя фьючерсы и обещания для передачи асинхронных результатов между потоками, а также std::packaged задачу для завершения вызова функции, которая может генерировать такой асинхронный результат. Предложение фьючерсов подверглось критике, потому что в нем отсутствует способ объединения фьючерсов и проверки выполнения одного обещания в наборе обещаний. Дополнительные высокоуровневые резьбовые сооружения, такие как пулы резьбы, были перенаправлены в будущий технический отчет C ++. Они не являются частью C++11, но их возможная реализация, как ожидается, будет построена полностью на вершине функций библиотеки потоков. Новая функция std::async обеспечивает удобный способ выполнения задач и привязки их к std::future. Пользователь может выбрать, будет ли задача выполняться асинхронно в отдельной нити или синхронно в потоке, который ожидает значения. По умолчанию, реализация может выбирать, что обеспечивает простой способ использования преимуществ аппаратного конкурентности без переподписки и обеспечивает некоторые из преимуществ пула потоков для простых применений.
Умные указатели общего назначения
C++11 предоставляет , и улучшения к и от TR1. не используется.
Устраненные или устаревшие функции
Термин "точка последовательности" был удален, и был заменен указанием, что одна операция секвенируется перед другой или что две операции не секвенированы. Было устранено прежнее использование ключевого слова "экспорт". Само ключевое слово остается, будучи зарезервированным для потенциального будущего использования. Спецификации динамических исключений устарели. Спецификация времени компиляции функций бросания без исключений доступна с ключевым словом noexcept, которое полезно для оптимизации. std::auto ptr устарел, его заменил std::unique ptr. Классы базовых объектов функций (std::unary function, std::binary function), адаптеры для указателей на функции и адаптеры для указателей на элементы, а также классы связующих элементов все устарели.