C++ 14

C++14 —վերջին ստանդարտի ոչ պաշտոնական անվանումը C++ ISO/IEC JTC1 է (ամբողջական անվանումը՝ «International Standard ISO/IEC 14882:2014(E) Programming Language C++». C++14 ը կարելի է դիտարկել որպես C++11-ի փոքրիկ ընդլայնում, որը հիմնականում պարունակում է սխալների ուղղում և որոշակի բարելավում։ Նոր ստանդարտը մշակող հանձնաժողովը N3690 սևագիրը թողարկեց 2013 թվականի մայիսի 15-ին։ N3936 սևագրի աշխատող տարբերակը թողարկվեց 2014 թվականի մարտի 2-ին, քվեարկության վերջնական փուլը ավարտվեց 2014 թվականի օգոստոսի 15-ին, իսկ արդյունքները ( միաձայն հավանությամբ ) հայտարարվեցին 2014 թվականի օգոստոսի 18 ին։
Քանի որ ստանդարտի մշակումը երկարատև էր, իսկ վերջնական տարբերակի հրապարակման թիվը հստակ չէր, մշակման ընթացքում օգտագործվում էր «C++1y» անունը, ինչպես C++11-ը, մինչ թողարկումը անվանում էին «C++0x» ( այս տարբերակի թողարկումը սպասվում էր մինչ 2010 թվականը)։
Ներքևում նկարագրվող լեզվի հնարավորությունները համապատասխանում են N3797 աշխատող սևագրին։ Հնարավոր է ստանդարտի վերջնական տարբերակից մի փոքր տարբերվեն։


== Լեզվում կատարված փոփոխություններ ==
Այս բաժնում ներկայացված են C++14 լեզվի միջուկի նոր հնարավորությունները։


=== Վերադարձվող արժեքի տիպի դուրսբերումը ֆունկցիայի համար ===
C++11 թույլ է տալիս դուրս բերել լյաբդա-ֆունկցիաների վերադարձվող արժեքի տիպը, վերադարձվող արտահայտության տիպից։ C++14-ում այդ հնարավորությունը ընդգրկում է բոլոր ֆունկցիաները։ Նոր ստանդարտը լյաբդա-ֆունկցիաների համար նաև նկարագրում է տիպերի դուրսբերումը return expression-ից տարբերվող դեպքերում։
Վերադարձվող արժեքի տիպի ավտոմատ դուրս բերման համար ֆունկցիայի վերադարձվող արժեքի տիպը պետք է հայտարարված լինի auto, բայց ի տարբերություն նախորդ ստանդարտի ֆունկցիայի հայտարարման վերջում վերադարձվող տիպը բացահայտ նշելու կարիք չկա։

Եթե ֆունկցիայի մարմնի տարբեր մասերից վերդարձնում է մի քանի արտահայտություններ, ապա այդ արտահայտություններից վերադարձվող տիպը պետք է նույնը լինի բոլոր արտահայտությունների համար։ Ֆունկցիաները՝ որոնք ավտոմատ կերպով են վերադարձնում տիպը, հնարավոր է օգտագործել նախնական հայտարարումը, սակայն հնարավոր է օգտագործել սահմանելուց հետո։ Այս սահմանումների թարգմանությունը պետք է հասանելի լինեն նույն տեղում որտեղ, որ օգտագործում են։


=== Այլընտրանքային եղանակով տիպի դուրս բերումը հայտարարելու ժամանակ ===
C++11-ում հնարավոր էր տիպը դուրս բերել երկու եղանակով։ auto-ն հնավարություն է տալիս ստեղծել փոփոխականներ որոնց տիպը հիմնականում որոշվում է այն արտահայտությունից որը վերագրվում է։ decltype-ը հնարավորություն է տալիս տիպը որոշել կամայական արտահայտությունից։ Մեծ մասամբ auto-ն վերադարձնում է ոչ հղումային տիպ, եթե մշակված լիներ որպես std::remove_reference, ապա կվերադարձներ հղումային տիպի auto&&։ Այդուհանդերձ decltype-ի տիպը կարող է լինել ինչպես հղումային այնպես էլ ոչ հղումային կախված արտահայտությունից։

C++14-ում ավելացվել է decltype(auto)։ decltype-ի այս գրելաձևը հնարավորություն է տալիս օգտագործել auto-ի հայտարարում։ decltype(auto) գրելաձևը հնարավոր է օգտագործել վերադարձվող արժեքի տիպը որոշելու համար, եթե ցույց տանք decltype(auto)-ի հետ auto-ն որտեղ ֆունկցիա արժեքը վերադարձնում է տիպը։


=== Հաստատուն արտահայտությունների սահմանափակումների նվազեցում ===
C++11-ում ներկայացված է constexpr ֆունկցիա հասկացությունը։ Այս հասկացությունը հնարավորություն է տալիս ֆունկցիան իրականացնել կոմպիլացիա ժամանակ։ Վերադարձված արժեքները կարող են օգտագործվել այնպիսի արտահայտություններում որտեղ արտահայտությունը հաստատուն է, օրինակ. որպես կաղապարի փոփոխական։ Այնուհանդերձ constexpr ֆունկցիան C++11-ում կարող է վերադարձնել միայն մեկ արժեք (ինչպես նաև static_assert-ը և մի քանի այլ ֆունկցիաներ )։
C++ 14 –ում այդ երևույթների մի մասը հանած է։ Հիմա constexpr ֆունկցիան կարող է ունենալ հետևյալ տարրերը։

Ցանկացած հայտարարում բացիstatic կամ thread_local փոփոխականներ
հայտարարել փոփոխակաները առանց սկզբնավորելուՊայմանական արտահայտությունների ճյուղավորումը if և switch
Բոլոր ցիկլիկ օպերատորների այդ թվում for-ի միջակայքերի համար
Արտահայտությունները, որոնք փոխել են օբյեկտի արժեքը և եթե այդ օբյեկտները ստեղծվել են constexpr հրամանով, ապա սա ներառում է կանչեր ցանկացած ոչ constconstexpr, ոչ ստատիկ ֆունկցիայի անդամների համար։goto-արտահայտությունում թույլ չի տալիս constexpr ֆունկցիաները C++14:
Սահմանափակումները ոչ constexpr ֆունկցիաների համար մնում է ուժի մեջ։ Այսպիսով եթե օգտագործում ենք for հրամանը միջակայքերի համար, ապա begin և end ֆունկցիաները կոնտեյնեռների համար պետք է լինեն գերբեռնված որպես constexpr։ Որպես կառուցողաղկան տիպ std::initializer_list ֆունկցիաները begin/end սահմանված են որպես constexpr ինչպես լոկալ, այնպես էլ ընդհանուր դեպքում։
Բացի այդ C ++ 11-ի բոլոր ոչ ստատիկ մեթոդները հայտարարել են ինչպես constexpr, վերջերս համարում էին const-ֆունկցիան դիմում է this-ին, բայց հիմա այդ սահմանափակումը հանած են, ոչ ստատիկ մեթոդները կարող են լինել ոչ const։ Այնուհանդերձ, ինչպես առաջ էր նշվում ոչ const constexpr մեթոդը կարող է փոխել դասսը այն դեպքում երբ այդ արտահայտությունը ստեղծվել է հաստատուն արտահայտության ստեղծման ժամանակ։


=== Փոփոխականների կաղապարներ ===
C++-ի նախորդ տարբերակներում կաղապարները սահմանված էր միայն ֆունկցիաների և դասերի համար։ C++14-ը թույլ է տալիս ստեղծել կաղապար փոփոխականներ։ Օրնակ պի թվի ներկայացումը կաղապար փոփոխականով, կաղապար փոփոխականին տալով պի-ն ստանում ես նրա արժեքը, ամբողջ տիպի համար այն կլինի 3 (ավելի ճշգրիտ արժեք ստանալու համար տիպը պետք է ընտրել float, double կամ long double և այլն )։
Այսպիսի հայտարարումները և սահմանումները պատկանում է կաղապարների կանոններին։


=== Դասերի համախառն սկզբնարժեքավորում դաշտերի սկզբնարժեքավորողներով ===
C++ 11-ում ավելացվել են դասերի դաշտերի սկզբնարժեքավորողներ- արտահայտություններ, կիրառվում է դաշտերի վրա դասի մակարդակում, եթե կոնստրուկտորը ինքնուրույն չի սկզբնարժեքավորում։ Ագրեգատների ինիցիալիզացումը փոփոխվել է, որպեսզի բացահայտորեն բացառի անդամների ինցիալիզացիաները, որովհետև դրանց համար ագրեգատայինինիցիալիզացիան անհար է։
C++14-ը հանում է այդ սահմանափակումը և ընդլայնում է դասերի համախառն սկզբնարժեքավորումը դաշտերի սկզբնարժեքավորողներով։ Եթե ձևավոր փակագծերի մեջ եղած սկզբնարժեքավորողների ցուցակը տվյալ արգումենտի համար արժեք չի հատկացնում, ապա այդ գործը իր վրա է վերցնում դաշտի սկզբնարժեքավորողը։


=== Երկուական թվերի լիտերալներ ===
Թվային լիտերալները C++14 ում կարելի է հայտարարել երկուական տեսքով։ Գրելաձևը օգտագործում է 0բ կամ 0Բ նախդիրները։ Նմանատիպ գրելաձև օգտագործվում է նաև Java, Python, Perl и D լեզուներում։


=== Կարգերի բաժանիչներ ===
C++14 –ում կարելի է օգտագործել ապաթարց թվային լիտերալներում կարգերի առանձնացման համար։ Որոշ դեպքերում դա հեշտացնում է մեծ հաստատունների ընկալումը և հեշտացնում է կոդի ընթերցելիությունը։


=== Ընդհանրացված լյամբդա-ֆունկցիաներ ===
C++11-ում լյամբդա-ֆունկցիաների պարամետրերը անհրաժեշտ է հայտարարել նշելով կոնկրետ տիպը։ C++14-ը հանում է այդ սահմանափակումը և թույլատրում է լյամբդա-ֆուկցիաների հայտարարումը auto հատուկ բառով։

Ընդհանրացված լյամբդա-ֆունկցիաների պարամետրերի տիպերի դուրսբերումը կատարվում է auto-փոփոխականների տիպերի դուրսբերման օրենքներով (բայց ամբողջովին նույնը չէ)։ Վերևում ներկայացված կոդը համարժեք է հետևյալին.


=== Լյամբդա-ֆունկցիաների արտահայտությունների ընդունումը ===
Լյամբդա-ֆունկցիաները C++11-ում թույլատրում են ընդունել ներքին տեսանելիության տիրույթում հայտարարված փոփոխականները, հղման կամ արժեքի փոխանցման ճանապարհով։ Դա նշանակում է որ չի կարելի արժեքով ընդունել միայն տեղափոխում թույլատրող( բայց կրկնօրինակում չթույլատրող ) տիպի փոփոխականները։ C++14-ը թույլատրում է ընդունել ցանկացած արտահայտությամբ սկզբնարժեքավորված փոփոխականներ։ Դրա շնորհիվ կարելի է ընդունել փոփոխականներ արժեքի տեղափոխումով և հայտարարել ավելի բարձր տեսանելույան տիրույթում չհայտատրարված անունով փոփոխականներ։
Արտահայտությունների ընդունումը իրականավում է սկզբնարժեքավորողների օգնությամբ

lambda լյամբդա-ֆունկցիան կվերադարձնի 1, քանի որ value պարամետրի համար աշխատել է համապատասխան սկզբնարժեքավորողը։ Ընդունված պարամետրի տրպը դուրս է բերվում սկզբնարժեքավորողի տիպից auto հատուկ բառի հայտարարության համաձայն։
lambda լյամբդա-ֆունկցիան կվերադարձնի 1, քանի որ value պարամետրի համար աշխատել է համապատասխան սկզբնարժեքավորողը։ Ընդունված պարամետրի տրպը դուրս է բերվում սկզբնարժեքավորողի տիպից auto հատուկ բառի հայտարարության համաձայն։


=== Ատրիբուտ deprecated ===
deprecated ատրիբուտը հնարավորություն է տալիս որոշակի երևույթներ նշել որպես հնեցված։ Այդպիսի երևույթների օգտագործման ժամանակ, կոմպիլյացիայի ընթացքում դուրս է բերվում զգուշացում։ deprecated ատրիբուտի արգումենտ կարող է հանդիսանալ տողային լիտեռալ, որը կբացատրի հնեցման պատճառը և/կամ դրա հնարավոր ալտերնատիվը։


== Ստանդարտ գրադարանի նոր ֆունկցաիներ ==


=== Բաժանվող մյուտեքսներ և կանխարգելում ===
C++14 ստանդարտում ավելացված են բաժանված (shared) մյուտեքսներ և նոր կանխարգելման եղանակ մյուտեքսների համար։


=== Չսահմանված որոնում կոնտեյներներում ===
C++ ստանդարտում գրադարնում սահմանված են չորս տեսակի ասոցատիվ դաս-կոնտեյներ։ Այդ դասերը հնարավորություն են տալիս արժեքների փնտրում հիմնվելով այդ դասի տիպի վրա։map կոնտեյներում նշվում է բանալիի և արժեքի տիպերը, իսկ որոնումը տեղի է ունենում բանալիով և վերադարձնում է արժեքը։ Ամեն դեպքում որոնումը կատարվում է ըստ բանալու՝ լինի դա բանալին map-ում թե արժեքը set-ում։ C++14 ստանդարտը թույլ է տալիս ստեղծել կամայական տիպի ասոցատիվ կոնտեյներներ. պայմանով, որ դրանք ունենան գերբեռնված համեմատման օպերատոր, որի միջոցով հնարավոր լինի համեմատել տվյալ տիպի օբյեկներ։ Սա հնարավորություն է տալիս std::string բանալու տիպով map-ում կատարել որոնում const char* տիպի օբյեկտի օգնությամբ օգտագործելով գերբեռնված operator<։Չսահմանված որոնումը թույլ է տալիս միայն այն ժամանակ, երբ կոնտեյներին փոխանցված կոմպարատորը ինքը թույլ է տալիս նման որոնումը։ Ստանդարտ գրադանի std::less և std::greater թույլ են տալիս կատարել չսահմանված որոնում։


=== Ստանդարտ օգտագործման լիտերալներ ===
C++11 ստանդարտում նկարագրված է օգտագործողի կողմից սահմանվող լիտեռալային նախաբառերի սահմանման գրելաձև, բայց դրանցից ոչ մեկ չի օգտագործվում ստանդարտ գրադարանում։ C++14 ավելացնում է հետևյալ ստանդարտ լիտեռալները.

«s»` std::basic_string տարբեր տիպերի համար
«h», «min», «s», «ms», «us», «ns» ՝ std::chrono::duration տիպի ժամանակային լիտեռալների համար
Երկու «s» լիտեռալները չեն ազդում իրար վրա, քանի որ տողային լիտեռալը աշխատում է միայն տողային լիտեռալի հետ, ժամանակայինը միայն թվերի։


=== Խմբակների հասցեավորումը տիպերով ===
std::tuple-ը, որը ավելացվել է C++11 ստանդարտում թույլ է տալիս միմյանց կցել մի քանի տարբեր տիպերի արժեքներ որոնք կինդեքսավորվեն կոմպիլյացիայի ժամանակ։C++14 ընդլայնում է խմբակների ֆունկցիոնալությունը թույլ տալով դրանց էլեմենտներին դիմել ոչ միայն ինդեքսով այլև տիպի միջոցով։ Եթե խմբակը պարումնակում է նույն տիպի մի քանի օբյեկտներ ապա տիպի միջոցով դրա անդամներին դիմելը կբերի կոմպիլյացիայի սխալի։


=== Ստանդարտ գրադարանի այլ փոփոխություններ ===
std::make_unique կարելի է օգտագործել ինչպես std::make_shared, std::unique_ptr տիպի օբյեկտների համար։ std::integral_constant-ի համար ավելացվել է գերբեռնված operator(), որը կոնստանտ արժեք է վերադարձնում։ std::begin/std::end գլոբալ ֆունկցիաների անալոգիայով ավելացվել է std::cbegin/std::cend, որոնք վերադաձնում են կոնստանտ իտերատորներ դիապազոնի սկզբի և վերջի վրա։


== Ծանոթագրություններ ==