C++17
Версії мови програмування C++ |
---|
C++17 — одна з попередніх версій стандарту ISO/IEC 14882 для мови програмування C++. Слідує після C++14. Специфікація C++17[1][2] дійшла до чорнової версії стандарту в березні 2017 року і, була остаточно затверджена 8 вересня 2017 року.[3] Стандарт офіційно опублікований у грудні 2017.[4]
- Видалили
register
. Слово register все ще залишається зарезервованим, але більше не означає нічого.[7]
- Видалили
++
дляbool
. Префіксний та постфіксний інкременти більше не валідні для операцій над типом bool.[8]
- Видалили
throw(A, B, C)
. Динамічна специфікація виключень для фунцій типуvoid f() throw(A, B, C);
більше не валідна. Залишивсяthrow()
як синонім доnoexcept(true)
.[9]
- Заборонили повторне оголошення статичних
constexpr
членів класу. Дляstruct X {static constexpr int n = 10;}; int X::n;
вже не є визначенням, а є зайвим, надлишковим оголошенням, яке не рекомендується до використання. ЧленX::n
неявно вбудований (inline).[10]
- Видалили
auto_ptr
,random_shuffle
, старі функції адаптери з<functional>
. Ці можливості були заборонені починаючи з C++11 та замінені на кращі компоненти. Їхні імена залишаються зарезервованими.[11]
- Видалили заборонені аліаси
iostream
. Причина така ж як і в попередньому випадку.[12]
- Видалили конструктори з
function
які приймають алокатор як аргумент. Не тільки семантика була не зрозумілою, але є й технічні проблеми зберігання алокатора в контексті, коли тип не відомий.[13]
- Заборонили деякі хідери бібліотеки
C
:<ccomplex>
,<cstdalign>
,<cstdbool>
,<ctgmath>
. Але хідер<ciso646>
не є забороненим.[14]
- Заборонили старі бібліотечні компоненти:
allocator<void>
,raw_storage_iterator
,get_temporary_buffer
,is_literal_type
,std::iterator
.[15]
- Повністю заборонили хідер
<codecvt>
. Він використовувався для перетворення рядкових літералів з одного типу кодування в інший. Проте зробити перетворення правильно було дуже важко, та документація була не правильною. Разом з ним заборонили утилітиwstring_convert
таwbuffer_convert
з<locale>
. Взамін, користувачам рекомендується використовувати спеціалізовані бібліотеки для обробки тексту.[16]
- Тимчасово заборонили
memory_order_consume
. Поточна семантика впорядкування роботи з пам'яттю «consume» виявилась неадекватною, впорядкування необхідно перевизначити. Ця робота все ще ведеться. Є сподівання що в наступній версії С++ вона буде готовою. Натомість, користувачам рекомендується використовувати «acquire» впорядкування, щоб не отримати неочікувані результати в майбутньому.[17]
- Заборонили
shared_ptr::unique
. Ця функція передбачає поведінку, яка по факту не надається.[18]
- Заборонили
result_of
. Натомість треба використовуватиinvoke_result
.[19]
Це зміни, які застосовуються без вашого відома або згоди.
- Специфікація винятків стала частиною системи типів. Специфікація винятків функції стала частиною типу функції:
void f() noexcept(true);
таvoid f() noexcept(false);
функції з двома різними типами. Вказівники на функції чутливі до специфікації виключень. (Але дві функціїf
не можуть сформувати перевантажений набір). Ця зміна зміцнює систему типів, оскільки дозволяє API вимагати колбеки що не кидають виключень.[20]
- Гарантований пропуск створення тимчасової копії. Сенс
prvalue
таglvalue
було переглянуто.prvalues
більше не є об'єктом, а лише ініціалізацією. Функції, що повертаютьprvalues
більше не створюють копію об'єкта («mandatory copy elision»). Додали нове перетворенняprvalue-to-glvalue
, яке називається тимчасовою матеріалізацією перетворення. Ця зміна означає що зайва копія не буде створена. Це також стосується типів які не можна копіювати чи переміщати. Це дозволяє оголошувати функції які повертають такі типи.[21]
- Динамічне виділення пам'яті для даних з надлишковим вирівнюванням. Динамічне виділення пам'яті (operator new) тепер підтримує типи з надлишковим вирівнюванням. Нова перевантажена функція приймає параметр вирівнювання.[22]
- Строгіший порядок обчислення виразу. Порядок обчислення певного підвиразу було визначено краще, ніж раніше. Важливим прикладом цієї зміни є те, що аргументи функції тепер вираховуються у невизначеному порядку (indeterminately sequenced). Раніше цього не було в специфікації. Зверніть увагу, що порядок обчислення перевантажених операторів залежить від того, як вони викликані: коли вони викликаються з використанням синтаксису оператора, то порядок є таким самим, як і для вбудованих операторів, але якщо вони викликаються з використанням синтаксису виклику функції, то порядок такий самий як і для звичайної функції (тобто невизначений).[23][24]
Це зміни, які ви можете використовувати
- Символьний літерал
u8
, наприкладu8'a'
. Такий літерал має типchar
і його значення відповідає кодовій точці ISO 10646 (мається на увазі, що значення представляє собою один кодовий юніт UTF-8).[25]
- Шістнадцяткове подання літералів чисел з рухомою комою (Hexadecimal floating point literals). Літерали чисел з рухомою комою можуть бути записані з шістнадцятковим представлення основи та десятковим поданням експоненти:
0xC.68p+2, 0x1.P-126
. Це дозволяє точно (на багатьох платформах) передавати числа з рухомою комою (тобто літерал точно відповідає представленню числа в пам'яті). С підтримує цей синтаксис починаючи з С99, аprintf
підтримує його через%a
.[26]
- Розгортання запакованих виразів. Зручний синтаксис для ітеративного застосування бінарного оператора до елементів пачки параметрів:
template <typename ...Args> auto f(Args ...args) { return (0 + ... + args); }
[27][28]
- template <auto>. Дозволили оголошувати параметри шаблону, використовуючи auto[29]. Наприклад:
template<auto X> struct B { static constexpr auto value = X; };
B<5> b1; // OK: template parameter type is int
B<'a'> b2; // OK: template parameter type is char
B<2.5> b3; // error: template parameter type cannot be double
- Вивід типу аргумента шаблонного класу. Тип аргумента шаблонного класу можна вивести з конструктора. Наприклад
pair p(1, 'x');
визначиться якpair<int, char>
. Неявний вивід типів виконаний системою згідно з правилами явного виводу типів, що дозволяє розробникам змінювати правила виводу або повністю його заборонити[30][31][32][33]
- constexpr if. Під час спеціалізації шаблону (під час компіляції), значення виразу в середині
if constexpr (condition)
інстанціюється тільки тоді, коли виконуєтьсяcondition
(який має бути константним виразом).[34]
- Ініціалізація виразу в умові. В умовах
if
таswitch
з'явилася нова, необов'язкова частина, що дозволяє ініціалізувати нову, локальну зміну:[35]
if (auto it = m.find(key); it != m.end())
return it->second;
- constexpr лямбди. Лямбда вирази можуть бути константними виразами:
auto add = [](int a, int b) constexpr { return a + b; }; int arr[add(1, 2)];
[36]
- Захоплення лямбдою
*this
. Раніше[self = *this]{ self.f(); }
. Тепер[*this]{ f(); }
.[37]
inline
змінні. Додавання кваліфікатора inline до змінних дозволяє їх визначати в заголовному файлі (механізм аналогічний до inline functions).[10]
- Структуровані зв'язки.
auto [it, ins] = m.try_emplace(key, a1, a2, a3);
. Масиви, всі публічні члени класу та типи що підтримують протоколget<N>
, такі якpair
таtuple
розкладаються на елементи, які напряму привласнються оголошеним змінним.[38][39]
__has_include
. Оператор препроцесора, який перевіряє наявність header файлу.[40]
- Атрибути
[[fallthrough]]
,[[nodiscard]]
,[[maybe_unused]]
. Новий сет стандартизованих атрибутів. Формально вони не мають строгої семантики, але розробникам компіляторів рекомендується генерувати або пропускати відповідне попередження (warning).[41][42][43]
launder
. Засіб підтримки мови («межа оптимізації»), що дозволяє бібліотекам повторно використовувати місце зберігання даних, та доступатися до цього місця за старим вказівником. Раніше це не дозволялося. (Цей засіб розроблений для розробників компіляторів. Він не має використовуватися в «звичайному» коді).[44]
- Тип
byte
. Новий тип визначений в<cstddef>
(не в<stddef.h>
, і тільки в просторі іменstd
!). Має всі атрибутиunsigned char
та визначає побітові операції.[45]
- Спеціальні математичні функції. Вміст міжнародного стандарту
ISO/IEC 29124:2010
(mathematical special functions) став частиною C++. Функції були додані тільки до<cmath>
, але не до<math.h>
, та доступні тільки в просторі іменstd
.[46]
- Файлова система. Вміст
Filesystems Technical Specification
став частиною С++. Бібліотека файлової системи дозволяє платформно-незалежну взаємодію з директоріями та структурами які схожі на директорії (можуть відображати контент, переносити файли і т. д.). В основному моделюється файлова системаPOSIX
, але вона є достатньо гнучкою щоб бути реалізованою для будь-якої іншої системи.[47][48][49][50][51][52]
- Паралелізм. Вміст
Parallelism Technical Specification
став частиною С++. Він додає нові перевантажені функції, що приймають додаткові параметри політики виконання алгоритмів. А також повністю нові алгоритми (дивись нижче). Підтримуються три політики виконання, що дозволяють виконувати алгоритм послідовно, паралельно та векторно.[53][54][55][56][57][58][59][60][61][62]
- Нові алгоритми.
Parallelism Technical Specification
додав декілька нових алгоритмів до стандартної бібліотеки. Причиною додавання став їх потенціал ефективного, паралельного виконання. Функції доступні в звичній, простій формі:for_each_n
,reduce
,transform_reduce
,exclusive_scan
,inclusive_scan
,transform_exclusive_scan
,transform_inclusive_scan
. Зауважте, щоreduce
виглядає так само, як уже наявнийaccumulate
, але не гарантує певного порядку виконання операцій.[53]
- Новий тип:
string_view
(таbasic_string_view
). Новий класstring_view
є рекомендованим типом для API, які хочуть читати текстовий рядок але не мають наміру володіти ним чи модифікувати. Він створюється з символьного вказівника (char pointer), але інші класи, схожі на текстовий рядок, мають пропонувати функції перетворення доstring_view
.[63][64][65]
- Новий тип:
any
. Типany
видяляє тип об'єкту та дозволяє його копіювати. По суті є три речі які ви можете робити зany
: 1. задати значення типуT
; 2. зробити його копію; 3. запитати чи він містить значення типуU
і отримати це значення при умові, колиU
цеT
.[63][66][67]
- Новий шаблонний клас:
variant
. Він моделює розділене об'єднання. Типvariant<A, B, C>
містить значення якогось одного типуA
,B
абоC
в будь-який момент часу.[68][69][66][70][71]
- Новий шаблонний клас:
optional
. Значення не є обов'язковим. Типoptional<T>
представляє собою або значення типуT
, або те, що значення відсутнє (що визначається типомnullopt_t
). Деякою мірою це є еквівалентомvariant<nullopt_t, T>
, але з інтерфейсом, що було спеціально сконструйовано для даної задачі.[63][72][67][66]
invoke
. Можливіть одинаково викликати сутності, що можуть бути викликаними. Це дозволяє користувачам писати бібліотеки з поведінкою, ідентичною до правила INVOKE.[73]
is_invocable
,is_invocable_r
,invoke_result
. Властивості об'єкту. Чи може він бути викликаним та результат виклику.[74][19]
- Елементарне перетворення тектових рядків. Функції
to_chars
таfrom_chars
дозволяють створювати або зчитувати текстові рядки, представлені числами. Вони були додані до стандарту як ефективна, низькорівнева заміна операціям форматуванняprintf
таiostream
. Вони слідують ідеоматичним алгоритмічним стилям С++.[75]
- Шаблон
void_t
.template <class...> using void_t = void;
Даний псевдонім несподівано користий для метапрограмування. Дозволяє спростити використання SFINAE.[76]
- Шаблон
bool_constant
.template <bool B> using bool_constant = integral_constant<bool, B>
[77]
- Метафункції логічних операції. Метафункції, зі змінною кількістю параметрів для метапрограмування:
conjunction
,disjunction
таnegation
. Ці властивості важливі в метапрограмуванні: спеціалізації шаблону не створюються якщо від них не вимагають визначити результат.[78]
- Властивості для SFINAE-сумісного
swap
. Нові властивостіis_swappable
,is_nothrow_swappable
,is_swappable_with
,is_nothrow_swappable_with
.[79]
- Властивість
is_aggregate
. Вказує чи тип є складеним. Складеними є всі масиви та класи, в яких відсутні конструктори, що були оголошені користувачем, немає приватних або захищених нестатичних членів, відсутні базові класи та віртуальні функції. Властивість користна для того, щоб визначити чи загальний тип може бути створений за допомогою списку ініціалізації {} (list-initialized
чиnon-list-initialized
).[80]
- Властивість
has_unique_object_representations
. ЯкщоT
об'єкт, який можна тривіально копіювати, і якщо будь-які два об'єкти типуT
з одинаковим значенням мають одинакове представлення об'єкту, то значенняhas_unique_object_representations
буде true. Для будь-якого іншого типу, значення буде false.[81]
as_const
. Задане lvalue x буде повернуто функцієюas_const(x)
як константна версія. Не працює з rvalues.[82]
- Вільні функції
size
,data
таempty
. Додаткові функції доповнюють наявні вільні функціїbegin
/end
і т. ін. для доступу до масивів одноманітним чином. Зауважте, що на відміну відbegin
/end
, нові функції не є точками налаштування (customization points[83]) і надаються виключно для зручності.[84]
clamp
.clamp(x, low, high)
повертає x, якщо x знаходиться в інтервалі [low, high]. В протилежному випадку - найближу межу.[85]
gcd
таlcm
. Функції з теорії чисел для обчислення найбільшого спільного дільника та найменшого спільного кратного двох чисел.[86]
- Клас
shared_mutex
. Багато агентів виконання можуть одночасно мати право на читання спільного м'ютекса. Але жодний агент виконання не має право на читання, поки інший агент утримує ексклюзивний блок і виконує запис.[87]
- Розмір лінії кешу. Нові константи
hardware_constructive_interference_size
таhardware_destructive_interference_size
дозволяють платформі надати розмір її лінії кешу. Таким чином користувач може уникнути хибного спільного доступу (destructive interference) та покращити локальність (constructive interference).
В прикладі
struct keep_apart {
alignas(hardware_destructive_interference_size) atomic<int> cat;
alignas(hardware_destructive_interference_size) atomic<int> dog;
};
змінні cat та dog будуть знаходитися в різних лініях кешу. Це дозволить одночасно змінювати їхні значення з різних потоків.
І навпаки, якщо ми хочемо щоб змінні знаходились в одній лінії кешу (для покращення локальності), ми можемо перевірити розмір структури на етапі компіляції:
struct together {
atomic<int> dog;
int puppy;
};
struct kennel {
// Other data members...
alignas(sizeof(together)) together pack;
// Other data members...
};
static_assert(sizeof(together) <= hardware_constructive_interference_size);
Теоретично, значення hardware_constructive_interference_size
та hardware_destructive_interference_size
має бути одинаковим, але для підтримки неоднорідних архітектур було вирішено зробити дві константи.[88]
apply
. Викликає функцію або функтор f з аргументами tuple.[63]
int add(int first, int second)
{
return first + second;
}
int main()
{
std::cout << std::apply(add, std::make_tuple(1,2)) << '\n'; // output '3'
}
- Створення об'єктів з
tuple
. Нова шаблонна функціяmake_from_tuple
ініціалізує тип Т значеннями елементів кортежу. Нагадує функціюapply
, що застосована до конструктора.[89]
- Універсальний інвертор
not_fn
. Обгортка, що інвертує результат виклику функції. Працює з об'єктами будь-якої арності, та має замінити старі обгорткиnot1
таnot2
.[90][91]
struct LessThan7 : std::unary_function<int, bool>
{
bool operator()(int i) const { return i < 7; }
};
int main()
{
std::vector<int> v{0,1,2,3,4,5,6,7,8,9,10};
std::cout << std::count_if(begin(v), end(v), LessThan7()) << "\n"; // Output '7'
std::cout << std::count_if(begin(v), end(v), std::not1 (LessThan7())) << "\n"; // Output '4' (deprecated)
std::cout << std::count_if(begin(v), end(v), std::not_fn(LessThan7())) << "\n"; // Output '4' (recommended)
}
- Ресурси пам'яті
memory_resource
. Новий набір компонентів що включає в себе базовий клас ресурсу пам'яті (memory_resource
) для динамічного обрання провайдерів пам'яті. А також три конкретні реалізації (synchronized_pool_resource
,unsynchronized_pool_resource
таmonotonic_buffer_resource
). Дивись нижче варіанти використання.[63]
- Поліморфний алокатор. Алокатор, що використовує ресурси пам'яті, які можна змінювати під час виконання і які не є частиною типу алокатора. Містить зручний псевдонім
std::pmr::vector<T> = std::vector<T, polymorphic_allocator<T>>
[63][92]
- Функтори пошуку. Функтори для пошуку підрядку, що реалізують алгоритми Бойєра-Мура і Бойєра-Мура-Хорспула, та алгоритми пошуку, що використовують ці алгоритми.[63][93]
static_assert
з одним аргументом. Використанняstatic_assert
більше не вимагає другого аргументу:static_assert(N > 0);
.[94]
- Оголошення вкладених
namespace
. Наприклад:namespace X::Y { … }
замістьnamespace X { namespace Y { … }}
[95]
- Дозволили використовувати
typename
в шаблоні який знаходиться в середині параметрів другого шаблона (template <template <typename> typename Tmpl> struct X;
). Раніше шаблонні параметри шаблону були змушені використовувати ключове словоclass
.[96]
- Оператор
for
приймає параметри begin/end різних типів. Переписане правило дляfor (decl : expr)
тепер кажеauto __begin = begin-expr; auto __end = end-expr;
замістьauto __begin = begin-expr, __end = end-expr;
. Це створює основу для майбутньої підтримки операторомfor
діапазонів (ranges), робота над якими ще триває.[97]
- Розгортання пачки параметрів типів в оголошеннях
using
.template <typename ...Args> struct X : Args... { using Args::f...; };
[98]
- Ініціалізація значень фіксованих перелічень (
fixed-enums
). C++11 додав можливість оголошення нового типу цілих чисел, який не може неявно перетворюватися в інший тип. Ця техніка дуже корисна якщо потрібно уникнути анархічних, неявних перетворень С++, що були успадковані з С. Проте існувала одна незручність: ініціалізація значення нового типу вимагала використання static_cast або функціональної нотації (b = int (a);). Цим виправленням дозволили використовувати спрощену форму ініціалізації фіксованих перелічень.[99]
Наприклад
enum class Index : uint32_t { };
int main()
{
Index i1 { Index(5) }; // C++11 OK
Index i2 { 5 }; // C++11 error: cannot convert 'int' to 'Index' in initialization
Index i3 { 5 }; // C++17 OK
}
uncaught_exceptions()
. Функція uncaught_exception уже не підтримується. Нова функція uncaught_exceptions повертає кількість виключень, замість true/false. Попередня функція була непридатною до використання, дивись N4152 [Архівовано 16 листопада 2017 у Wayback Machine.] для подальшої інформації.[100]
- Атрибути в іменних просторах та переліченнях. Тепер в іменний простір та перелічення можна додати коментар з атрибутом. Це дозволяє, наприклад, позначити параметр як застарілий.[101]
enum OperationMode {
OM_Invalid,
OM_Normal,
OM_Terrified [[deprecated("re-named to invalid")]],
OM_AbortOnError [[deprecated("exceptions are used instead")]] = 4
};
namespace [[deprecated]] old_stuff{
void legacy();
}
- Можна використовувати
using
для іменних просторів атрибутів. Тепер замість:
void f() {
[[rpr::kernel, rpr::target(cpu,gpu)]] // repetition
do-task();
}
Можна писати так:
void f() {
[[using rpr: kernel, target(cpu,gpu)]]
do-task();
}
Це спрощення може допомогти, коли ви створюєте інструменти для автоматичного перекладу такого коду в іншу програмну модель.[102]
- Покращено вставку в асоціативні контейнери.
my_map.try_emplace(key, arg1, arg2, arg3)
нічого не робить якщо ключ уже існує в контейнері, в іншому випадку створює новий елемент. Інтерфейс гарантує, що rvalue reference аргументи не будуть переміщені, якщо вставка не відбулась.[103]
- Змінено тип, який повертає функція
emplace
. Послідовні контейнери які мають функції emplace_front та emplace_back раніше нічого не повертали (void emplace_front(…);). Тепер вони повертають зсилку на щойно створений елемент. (Ця зміна не вплинула на асоціативні контейнери, оскільки вони і раніше, завжди повертали ітератор на вставлений елемент).[104]
- Об'єднання асоціативних контейнерів (
map
таset
). До бібліотеки контейнерів додано новий механізм, що дозволяє переносити елементи між різними об'єктами map/set.[105][106]
set<int> src{1, 3, 5};
set<int> dst{2, 4, 5};
dst.merge(src); // Merge src into dst.
// src == {5}
// dst == {1, 2, 3, 4, 5}
Ця техніка також дозволяє змінювати ключ:
map<int, string> m{{1,”mango”}, {2,”papaya”}, {3,”guava”}};
auto nh = m.extract(2);
nh.key() = 4;
m.insert(move(nh));
// m == {{1,”mango”}, {3,”guava”}, {4,”papaya”}}
- Неконстантний
string::data
. Додали неконстантну перегрузку доbasic_string::data
що повертає вказівник на дані які можна модифікувати.[107]
- Версія
lock_guard
зі змінною кількістю аргументів називаєтьсяscoped_lock
. Новий шаблонний клас зі змінною кількістю аргументівscoped_lock<Args...>
одночасно захоплює декілька об'єктів синхронізації, використовуючи такий самий алгоритм якlock
та звільняє їх в деструкторі. Спершу, пропонувалося змінити визначенняlock_guard
, щоб додати можливість приймати змінну кількість аргументів, але виявилося, що ця зміна ламає наявну поведінку. Тому, натомість ми отримали новий класscoped_lock
, який однозначно кращий ніж старийlock_guard
та має використовуватися замість нього.[108][109]
- _v<T> шаблонні змінні. Добавлені some_trait_v<T> шаблонні змінні із значенням some_trait<T>::value для type trait стандартної бібліотеки..[110]
atomic::is_always_lock_free
. Новий константний, статичний членis_always_lock_free
документує чи операції з даним атомарним типом завжди вільні від блокувань (lock-free). Існуюча нестатична функція класуis_lock_free
може повертати різні відповіді для різних значень атомарного типу.[111]
shared_ptr
для масивів. Шаблонний класshared_ptr
тепер підтримує масиви в стилі С. Для цього конструктору треба передатиT[]
абоT[N]
як параметр шаблону, а конструкторshared_ptr
сам визначить відповідну функцію для очищення пам'яті.[63][112]
using std::string;
using std::shared_ptr;
using std::default_delete;
int arr_size{};
// C++14
auto string_arr_sptr_cpp14 = shared_ptr<string[]>(new string[arr_size], default_delete<string[]>() );
string_arr_sptr_cpp14.reset(new string[arr_size], default_delete<string[]>() );
// define an explicit deleter,
// or otherwise, "delete ptr;" will internally be used incorrectly!
// C++17
auto string_arr_sptr_cpp17 = shared_ptr<string[]>(new string[arr_size]);
string_arr_sptr_cpp17.reset(new string[arr_size]);
shared_ptr::weak_type
. До класуshared_ptr<T>
додали нове полеweak_type
, який є синонімомweak_ptr<T>
. Це дозволяє конструюватиweak_ptr
зshared_ptr
без явного вказання типуweak_ptr
.[113]
- Тривимірна гіпотенуза. Додано
hypot(x, y, z)
, як додатковий набір перегружених функцій, до <cmath> (але не до <math.h>, та тальки у простір іменstd
).[114]
- Додаткові алгоритми роботи з неініціалізованою пам'яттю. Додаткові алгоритми для створення об'єктів в неініціалізованій пам'яті та для видалення об'єктів. Керування пам'яттю без використання алокаторів, що надаються стандартною бібліотекою, є поширеною практикою як серед бібліотек користувачів, так і в самій стандартній бібліотеці. Наприклад, можна використовувати внутрішні буфери, або використовувати алокатори що не керують життєвим циклом об'єкта: bde [Архівовано 21 серпня 2015 у Wayback Machine.], sgi, eastl [Архівовано 22 жовтня 2017 у Wayback Machine.], bitsquid [Архівовано 10 жовтня 2017 у Wayback Machine.]. Написання власних алокаторів досить складна задача, тому мати декілька реалізацій таких алгоритмів допоможе розробникам бібліотек написання коректного та високоефективного коду. Було додано наступні алгоритми:
destroy_at
,destroy
таdestroy_n
— викликають деструктор для конкретного елемента.uninitialized_move
таuninitialized_move_n
— виконують створення елементів переміщенням (move construction) для діапазону пам'яті. Схоже наuninitialized_copy
uninitialized_value_construct
таuninitialized_value_construct_n
— виконують ініціалізацію об'єктів значеннями для діапазону пам'яті.uninitialized_default_construct
таuninitialized_default_construct_n
— виконують ініціалізацію об'єктів значеннями за замовчуванням для діапазону пам'яті.[115]
- Підтримка неповних типів для алокаторів. Ця зміна послаблює вимоги до алокаторів мати повний тип, що дозволяє використовувати такі рекурсивні структури як
struct X { std::vector<X> data; };
.[116]
- Зміни до
<chrono>
. Додали округлення вгору, вниз та до найближчого цілого для часових точок (floor
,ceil
,round
). Зробили більшість функційconstexpr
.[117][118]
constexpr
дляchar_traits
. Всі спеціалізації необхідні дляchar_traits
тепер мають constexpr функції-члениlength
,compare
,find
таassign
. Це дозволить більш широко використовувати текстові рядки в константних виразах.[119]
- Покращили
pair
таtuple
. Ця зміна робить конструкториpair
таtuple
такими ж явними, як і відповідний тип елементу конструктора.[120] Тепер можна писати так:
std::tuple<int, int> pixel_coordinates()
{
return {10, -15}; // OK
}
- C++ тепер посилається на C11. Стандарт C++ тепер нормативно посилається на C11 (ISO/IEC 9899:2011) як «Стандарт С». Не тільки ISO вимагає, щоб посилання на інші міжнародні стандарти посилались на останню опубліковану версію, а не історичну версію, але це також дає доступ до
aligned_alloc
, який корисний для вдосконалення менеджменту динамічної пам'яті.[14]
- Зарезервували іменні простори. Всі першорівневі простори імен вигляду stdX, де X це послідовність чисел, зарезервовані.[123]
- Короткий огляд бібліотеки С. Чисто редакційна зміна. Раніше, всі заголовки в частині «Бібліотека С» були представлені простим списком імен. Тепер це було змінено на детальний опис. Це робить зміни в семантиці С простішими до врахування в С++.[124]
- Визначення термінів «forwarding reference», «default member initializer», «templated entity» та «contiguous iterator». Ці зміни не мають нормативного впливу, але вони визначають офіційну термінологію для концептів, які тільки починають виникати з мовних правил. Точні та добре визначені терміни спрощують розмови про С++ та написання специфікації.[125][126][127][128]
- Заміна «генератор випадкових чисел» на «генератор випадкових бітів». Аналогічно, заміна не має нормативного впливу, але роз'яснює дизайн та наміри бібліотеки <random>.[129]
- ↑ N4661 Editors' Report -- Programming Languages -- C++. 21 березня 2017. Архів оригіналу за 4 лютого 2020. Процитовано 21 березня 2017.
- ↑ ISO/IEC DIS 14882: Programming Languages — C++ (PDF). Архів оригіналу (PDF) за 25 березня 2017.
{{cite web}}
: Cite має пустий невідомий параметр:|df=
(довідка) [Архівовано 2017-03-25 у Wayback Machine.] - ↑ C++17 is formally approved. Архів оригіналу за 29 січня 2020. Процитовано 10 жовтня 2017.
- ↑ ISO/IEC 14882:2017. Архів оригіналу за 17 травня 2013. Процитовано 23 січня 2018.
- ↑ N3981: Removing trigraphs??! (Richard Smith). 6 травня 2014. Архів оригіналу за 9 липня 2018. Процитовано 7 вересня 2017.
- ↑ IBM comment on preparing for a Trigraph-adverse future in C++17 [Архівовано 11 вересня 2018 у Wayback Machine.], IBM paper N4210, 2014-10-10. Authors: Michael Wong, Hubert Tong, Rajan Bhakta, Derek Inglis
- ↑ Remove Deprecated Use of the register Keyword. Архів оригіналу за 14 вересня 2017. Процитовано 13 вересня 2017.
- ↑ Remove Deprecated operator++(bool). Архів оригіналу за 11 вересня 2017. Процитовано 13 вересня 2017.
- ↑ Removing Deprecated Exception Specifications from C++17. Архів оригіналу за 13 вересня 2017. Процитовано 13 вересня 2017.
- ↑ а б Inline Variables (PDF). Архів оригіналу (PDF) за 29 серпня 2017. Процитовано 13 вересня 2017.
- ↑ Removing auto_ptr, random_shuffle(), And Old <functional> Stuff. Архів оригіналу за 20 жовтня 2017. Процитовано 7 вересня 2017.
- ↑ Remove Deprecated iostreams aliases. Архів оригіналу за 22 серпня 2017. Процитовано 13 вересня 2017.
- ↑ Removing Allocator Support in std::function (rev 1). Архів оригіналу за 17 вересня 2017. Процитовано 13 вересня 2017.
- ↑ а б C++17 should refer to C11 instead of C99. Архів оригіналу за 13 вересня 2017. Процитовано 13 вересня 2017.
- ↑ Deprecating Vestigial Library Parts in C++17. Архів оригіналу за 13 вересня 2017. Процитовано 13 вересня 2017.
- ↑ Deprecating <codecvt>. Архів оригіналу за 16 вересня 2017. Процитовано 13 вересня 2017.
- ↑ Temporarily discourage memory_order_consume. Архів оригіналу за 16 січня 2018. Процитовано 13 вересня 2017.
- ↑ Proposed Resolution for CA 14 (shared_ptr use_count/unique). Архів оригіналу за 7 липня 2017. Процитовано 13 вересня 2017.
- ↑ а б Resolving GB 55, US 84, US 85, US 86. Архів оригіналу за 5 липня 2017. Процитовано 13 вересня 2017.
- ↑ Make exception specifications be part of the type system. Архів оригіналу за 12 вересня 2017. Процитовано 18 вересня 2017.
- ↑ Wording for guaranteed copy elision through simplified value categories. Архів оригіналу за 12 вересня 2017. Процитовано 18 вересня 2017.
- ↑ Dynamic memory allocation for over-aligned data. Архів оригіналу за 8 вересня 2017. Процитовано 7 вересня 2017.
- ↑ Refining Expression Evaluation Order for Idiomatic C++ (PDF). Архів оригіналу (PDF) за 26 серпня 2018. Процитовано 18 вересня 2017.
- ↑ c++ - What are the evaluation order guarantees introduced by C++17?. Stack Overflow. Процитовано 7 лютого 2019.
- ↑ Adding u8 character literals. Архів оригіналу за 6 жовтня 2017. Процитовано 20 вересня 2017.
- ↑ Hexadecimal floating literals for C++. Архів оригіналу за 22 серпня 2017. Процитовано 20 вересня 2017.
- ↑ Unary Folds and Empty Parameter Packs (revision 1) (PDF). Архів оригіналу (PDF) за 9 грудня 2017. Процитовано 21 вересня 2017.
- ↑ Folding expressions. Архів оригіналу за 9 вересня 2017. Процитовано 21 вересня 2017.
- ↑ Declaring non-type template parameters with auto. Архів оригіналу за 16 вересня 2017. Процитовано 21 вересня 2017.
- ↑ Template argument deduction for class templates (Rev. 6). Архів оригіналу за 16 вересня 2017. Процитовано 21 вересня 2017.
- ↑ Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library. Архів оригіналу за 25 вересня 2017. Процитовано 21 вересня 2017.
- ↑ Class Template Argument DeductionAssorted NB resolution and issues (PDF). Архів оригіналу (PDF) за 7 липня 2017. Процитовано 21 вересня 2017.
- ↑ Drafting for class template argument deduction issues. Архів оригіналу за 5 липня 2017. Процитовано 21 вересня 2017.
- ↑ constexpr if: A slightly different syntax. Архів оригіналу за 7 жовтня 2017. Процитовано 22 вересня 2017.
- ↑ Selection statements with initializer. Архів оригіналу за 6 жовтня 2017. Процитовано 22 вересня 2017.
- ↑ Wording for Constexpr Lambda (PDF). Архів оригіналу (PDF) за 23 квітня 2017. Процитовано 22 вересня 2017.
- ↑ Lambda Capture of *this by Value as [=,*this]. Архів оригіналу за 22 серпня 2017. Процитовано 25 вересня 2017.
- ↑ P0217R3: Proposed wording for structured bindings. Архів оригіналу за 6 жовтня 2017. Процитовано 25 вересня 2017.
- ↑ P0615R0: Renaming for structured bindings. Архів оригіналу за 10 вересня 2017. Процитовано 25 вересня 2017.
- ↑ __has_include for C++17. Архів оригіналу за 1 жовтня 2017. Процитовано 25 вересня 2017.
- ↑ Wording for [[fallthrough]] attribute (PDF). Архів оригіналу (PDF) за 21 липня 2017. Процитовано 25 вересня 2017.
- ↑ Wording for [[nodiscard]] attribute (PDF). Архів оригіналу (PDF) за 21 липня 2017. Процитовано 25 вересня 2017.
- ↑ Wording for [[maybe_unused]] attribute (PDF). Архів оригіналу (PDF) за 21 липня 2017. Процитовано 25 вересня 2017.
- ↑ Core Issue 1776: Replacement of class objects containing reference members. Архів оригіналу за 10 вересня 2017. Процитовано 25 вересня 2017.
- ↑ A byte type definition (PDF). Архів оригіналу (PDF) за 6 червня 2017. Процитовано 25 вересня 2017.
- ↑ Mathematical Special Functions for C++17, v5 (PDF). Архів оригіналу (PDF) за 22 вересня 2017. Процитовано 26 вересня 2017.
- ↑ Adopt the File System TS for C++17. Архів оригіналу за 7 жовтня 2017. Процитовано 26 вересня 2017.
- ↑ Relative Paths for Filesystem (R1). Архів оригіналу за 26 вересня 2017. Процитовано 26 вересня 2017.
- ↑ Directory Entry Caching for Filesystem (R1). Архів оригіналу за 26 вересня 2017. Процитовано 26 вересня 2017.
- ↑ Adapting string_view by filesystem paths (PDF). Архів оригіналу (PDF) за 11 жовтня 2017. Процитовано 26 вересня 2017.
- ↑ P0430R2 – File system library on non-POSIX-like operating systems (PDF). Архів оригіналу (PDF) за 11 жовтня 2017. Процитовано 26 вересня 2017.
- ↑ Proposed Resolution of C++17 National Body Comments for Filesystems(R2). Архів оригіналу за 1 жовтня 2017. Процитовано 26 вересня 2017.
- ↑ а б The Parallelism TS Should be Standardized. Архів оригіналу за 6 жовтня 2017. Процитовано 26 вересня 2017.
- ↑ Better Names for Parallel Execution Policies in C++17 (PDF). Архів оригіналу (PDF) за 23 жовтня 2016. Процитовано 26 вересня 2017.
- ↑ P0394-r4: Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling. Архів оригіналу за 12 травня 2017. Процитовано 26 вересня 2017.
- ↑ P0452r1 Unifying <numeric> Parallel Algorithms. Архів оригіналу за 25 серпня 2017. Процитовано 26 вересня 2017.
- ↑ Iterator Concerns for Parallel Algorithms. Архів оригіналу за 5 липня 2017. Процитовано 26 вересня 2017.
- ↑ P0502r0 Throwing out of a parallel algorithm terminates—but how?. Архів оригіналу за 7 липня 2017. Процитовано 26 вересня 2017.
- ↑ P0518r1 Allowing copies as arguments to function objects given to parallel algorithms in response to CH11. Архів оригіналу за 5 липня 2017. Процитовано 26 вересня 2017.
- ↑ P0523R1: Wording for CH 10: Complexity of parallel algorithms. Архів оригіналу за 5 липня 2017. Процитовано 26 вересня 2017.
- ↑ P0574r1: Algorithm Complexity Constraints and Parallel Overloads. Архів оригіналу за 5 липня 2017. Процитовано 26 вересня 2017.
- ↑ P0623r0 Final C++17 Parallel Algorithms Fixes. Архів оригіналу за 5 липня 2017. Процитовано 26 вересня 2017.
- ↑ а б в г д е ж и Adopt Library Fundamentals V1 TS Components for C++17 (R1). Архів оригіналу за 4 листопада 2017. Процитовано 27 вересня 2017.
- ↑ Integrating std::string_view and std::string (PDF). Архів оригіналу (PDF) за 27 вересня 2017. Процитовано 27 вересня 2017.
- ↑ Literal suffixes for basic_string_view. Архів оригіналу за 27 вересня 2017. Процитовано 27 вересня 2017.
- ↑ а б в Revisiting in-place tag types for any/optional/variant. Архів оригіналу за 7 липня 2017. Процитовано 27 вересня 2017.
- ↑ а б Homogeneous interface for variant, any andoptional (Revision 3) (PDF). Архів оригіналу (PDF) за 27 вересня 2017. Процитовано 27 вересня 2017.
- ↑ Variant: a type-safe union for C++17 (v8). Архів оригіналу за 14 жовтня 2017. Процитовано 28 вересня 2017.
- ↑ Disallowing references, incomplete types, arrays, and empty variants. Архів оригіналу за 7 липня 2017. Процитовано 28 вересня 2017.
- ↑ Homogeneous interface for variant, any andoptional (Revision 3) (PDF). Архів оригіналу (PDF) за 27 вересня 2017. Процитовано 27 вересня 2017.
- ↑ Making Variant Greater Equal. Архів оригіналу за 16 березня 2017. Процитовано 28 вересня 2017.
- ↑ Making Optional Greater Equal Again (PDF). Архів оригіналу (PDF) за 28 вересня 2017. Процитовано 28 вересня 2017.
- ↑ A proposal to add invoke function template (Revision 1). Архів оригіналу за 6 жовтня 2017. Процитовано 28 вересня 2017.
- ↑ is_callable, the missing INVOKE related trait. Архів оригіналу за 3 листопада 2017. Процитовано 28 вересня 2017.
- ↑ P0067R5: Elementary string conversions, revision 5. Архів оригіналу за 13 вересня 2017. Процитовано 28 вересня 2017.
- ↑ TransformationTrait Alias void_t (PDF). Архів оригіналу (PDF) за 28 серпня 2017. Процитовано 29 вересня 2017.
- ↑ Wording for bool_constant, revision 1. Архів оригіналу за 14 жовтня 2017. Процитовано 29 вересня 2017.
- ↑ Logical Operator Type Traits (revision 1). Архів оригіналу за 3 листопада 2017. Процитовано 29 вересня 2017.
- ↑ Adding [nothrow-]swappable traits, revision 3. Архів оригіналу за 24 липня 2017. Процитовано 29 вересня 2017.
- ↑ C++ Standard Library Defect Report List (Revision D106). Архів оригіналу за 29 вересня 2017. Процитовано 29 вересня 2017.
- ↑ has_unique_object_representations - wording. Архів оригіналу за 3 листопада 2017. Процитовано 29 вересня 2017.
- ↑ Constant View: A proposal for a std::as_const helper function template. Архів оригіналу за 20 червня 2017. Процитовано 4 жовтня 2017.
- ↑ Customization Point Design in C++11 and Beyond. Архів оригіналу за 4 жовтня 2017. Процитовано 4 жовтня 2017.
- ↑ Non-member size() and more (Revision 2) (PDF). Архів оригіналу (PDF) за 8 січня 2019. Процитовано 4 жовтня 2017.
- ↑ An algorithm to "clamp" a value between a pair of boundary values (revision 1). Архів оригіналу за 3 листопада 2017. Процитовано 4 жовтня 2017.
- ↑ Adopt Selected Library Fundamentals V2 Components for C++17 (PDF). Архів оригіналу (PDF) за 7 липня 2017. Процитовано 4 жовтня 2017.
- ↑ N4508: A proposal to add shared_mutex (untimed). Архів оригіналу за 3 листопада 2017. Процитовано 4 жовтня 2017.
- ↑ P0154R1 constexpr std::hardware_{constructive,destructive}_interference_size.
- ↑ P0209r2 | make_from_tuple: apply for construction (PDF). Архів оригіналу (PDF) за 7 липня 2017. Процитовано 4 жовтня 2017.
- ↑ Adopt not_fn from Library Fundamentals 2 for C++17. Архів оригіналу за 17 жовтня 2017. Процитовано 4 жовтня 2017.
- ↑ Fixes for not_fn. Архів оригіналу за 3 листопада 2017. Процитовано 4 жовтня 2017.
- ↑ P0337r0 | Delete operator= for polymorphic_allocator. Архів оригіналу за 23 жовтня 2016. Процитовано 4 жовтня 2017.
- ↑ Fixing a design mistake in the searchers interface in Library Fundamentals (PDF). Архів оригіналу (PDF) за 4 жовтня 2017. Процитовано 4 жовтня 2017.
- ↑ Extending static_assert, v2 (PDF). Архів оригіналу (PDF) за 11 серпня 2015. Процитовано 7 вересня 2017.
- ↑ Nested namespace definition (revision 2). Архів оригіналу за 3 серпня 2015. Процитовано 7 вересня 2017.
- ↑ Allow typename in a template template parameter. Архів оригіналу за 11 серпня 2015. Процитовано 7 вересня 2017.
- ↑ Generalizing the Range-Based For Loop. Архів оригіналу за 5 жовтня 2017. Процитовано 6 жовтня 2017.
- ↑ Pack expansions in using-declarations. Архів оригіналу за 17 жовтня 2017. Процитовано 6 жовтня 2017.
- ↑ Construction Rules for enum class Values (PDF). Архів оригіналу (PDF) за 9 грудня 2017. Процитовано 6 жовтня 2017.
- ↑ Wording for std::uncaught_exceptions (PDF). Архів оригіналу (PDF) за 8 січня 2019. Процитовано 9 жовтня 2017.
- ↑ Attributes for namespaces and enumerators. Архів оригіналу за 6 жовтня 2017. Процитовано 9 жовтня 2017.
- ↑ Using attribute namespaces without repetition. Архів оригіналу за 12 жовтня 2017. Процитовано 9 жовтня 2017.
- ↑ Improved insertion interface for unique-key maps (Revision 2.3). Архів оригіналу за 22 серпня 2017. Процитовано 9 жовтня 2017.
- ↑ Emplace Return Type (Revision 2) (PDF). Архів оригіналу (PDF) за 7 липня 2017. Процитовано 9 жовтня 2017.
- ↑ Splicing Maps and Sets (Revision 5) (PDF). Архів оригіналу (PDF) за 7 липня 2017. Процитовано 9 жовтня 2017.
- ↑ Wording for GB 58. Архів оригіналу за 7 липня 2017. Процитовано 9 жовтня 2017.
- ↑ Give 'std::string' a non-const '.data()' member function. Архів оригіналу за 3 листопада 2017. Процитовано 9 жовтня 2017.
- ↑ Variadic lock_guard (Rev. 3). Архів оригіналу за 24 жовтня 2017. Процитовано 9 жовтня 2017.
- ↑ Variadic lock_guard (Rev. 5). Архів оригіналу за 24 вересня 2017. Процитовано 9 жовтня 2017.
- ↑ Adopt Type Traits Variable Templates from Library Fundamentals TS for C++17. Архів оригіналу за 21 липня 2017. Процитовано 9 жовтня 2017.
- ↑ P0152R1 constexpr atomic<T>::is_always_lock_free. Архів оригіналу за 19 вересня 2017. Процитовано 9 жовтня 2017.
- ↑ Merging shared_ptr changes from Library Fundamentals to C++17. Архів оригіналу за 9 жовтня 2017. Процитовано 9 жовтня 2017.
- ↑ shared_ptr::weak_type. Архів оригіналу за 6 квітня 2017. Процитовано 10 жовтня 2017.
- ↑ Proposal to Introduce a 3-Argument Overload to std::hypot (PDF). Архів оригіналу (PDF) за 5 червня 2017. Процитовано 10 жовтня 2017.
- ↑ Extending memory management tools. Архів оригіналу за 6 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ Minimal incomplete type support for standard containers, revision 4. Архів оригіналу за 3 листопада 2017. Процитовано 10 жовтня 2017.
- ↑ Difference from previous revision. Архів оригіналу за 19 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ Wording for GB 50. Архів оригіналу за 3 листопада 2017. Процитовано 10 жовтня 2017.
- ↑ Constexpr for std::char_traits. Архів оригіналу за 10 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ Improving pair and tuple, revision 3. Архів оригіналу за 29 вересня 2017. Процитовано 10 жовтня 2017.
- ↑ Resolving LWG Issues re common_type (PDF). Архів оригіналу (PDF) за 10 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ common_type and duration (PDF). Архів оригіналу (PDF) за 5 липня 2017. Процитовано 10 жовтня 2017.
- ↑ Reserve a New Library Namespace Future Standardization. Архів оригіналу за 10 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ Synopses for the C library. Архів оригіналу за 11 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ Wording for Forwarding References (PDF). Архів оригіналу (PDF) за 4 серпня 2016. Процитовано 10 жовтня 2017.
- ↑ Introducing a name for brace-or-equal-initializers for non-static data members. Архів оригіналу за 3 серпня 2016. Процитовано 10 жовтня 2017.
- ↑ P0391R0: Introducing the term "templated entity". Архів оригіналу за 23 жовтня 2016. Процитовано 10 жовтня 2017.
- ↑ N4284: Contiguous Iterators. Архів оригіналу за 6 жовтня 2017. Процитовано 10 жовтня 2017.
- ↑ A <random> Nomenclature Tweak (PDF). Архів оригіналу (PDF) за 10 жовтня 2017. Процитовано 10 жовтня 2017.
- Відмінності між C++14 та C++17 [Архівовано 12 листопада 2020 у Wayback Machine.]