Az új szabvány egy fontos pontban módosítja a C++ szintaxisát. A régi
C++-ban a >>
karaktersorozat minden esetben a shift
right
operátort jelentette, így egymásba ágyazott template-ek deklarálásakor szóközt
kellett a két záró >
közé tenni. Az új szabvány szerint azonban sablonok használatakor
ez a jelentése élvez elsőbbséget. Bizonyos esetekben így is syntax error-t kapunk, ezt a viselkedést zárójelezéssel lehet
megváltoztatni:
A standard C++-ban kétféle string literált használhattunk ezelőtt.
" "közötti szöveg, ami lényegében egy 0-ra végződő
const chartömb
L"..."jelöléssel használható, ami egy 0-ra végződő
const wchar_ttömb, ahol
wchar_twide-karakter
Az új C++-ban három Unicode kódolás támogatása is megtalálható, használhatóak UTF-8, UTF-16 illetve UTF-32 kódolású sztring
literálok is. Ezek típusa rendre const char[]
,
const char16_t[]
és const char32_t[]
lesz. A következőképpen hozhatóak
létre:
A literálokba konkrét Unicode karaktereket is be tudunk szúrni 16 bites kódolásban
a \u
, 32 bites kódolásban a \U
előtaggal:
Új hasznos funkció a raw
literál. A literál kezdetét R"DELIMITER(, végét
)DELIMITER" karaktersorozattal jelezhetjük, ahol a DELIMITER egy tetszőleges általunk választott (maximum 16 hosszú) karaktersorozat.
A két zárójel közötti rész lesz maga a sztring, amely tartalmazhat "
és /
anélkül, hogy escape karaktert kellene használnunk.
Az új C++ nyelvben lehet saját literálokat definiálni. Az új literált az utótagja alapján lehet azonosítani, definiálása pedig a "" operátor definiálásával történik:
Egész, vagy lebegőpontos alaptípusok esetén az operátorok deklarációjának létezik "cooked" (az érték átadása unsigned long long-ként vagy long double-ként) és "uncooked" változata is (az érték átadása char*-ként):
Sztringekre a következő formák léteznek a sztringliterál fajtája szerint:
Fordítás idejű ellenőrzésekre az új static_assert
kulcsszó használható (szemben az assert
makróval, amely runtime ellenőrzésekhez használatos):
A fordító kiértékeli a kifejezést (expression), és kiírja a string üzenetet, ha a kiértékelés eredménye hamis. (assertion failed) Például:
A régi C++-ban nem konstans referenciákat lehetett balértékekhez (lvalue) kötni, konstansokat pedig bal-, és jobbértékekhez egyaránt. Viszont nem volt semmi, amit hozzá lehetett kapcsolni egy nem konstans jobbértékhez. Tekintsük a következő példát:
Ha incr(0) engedélyezve lenne, akkor egyrészt egy senki által nem használt temporáris változó meg lenne növelve eggyel, és ami sokkal rosszabb, ezentúl 0 értéke 1 lenne. Ez elsőre furcsán hangzik, de volt egy hasonló bug a korai Fortran fordítókban. Ezek után tekintsük a következő cserélőfüggvényt
Ha T típus valami bonyolult típus, akkor a fenti swap függvény egy elég költséges függvény lehet. Sőt, igazából nekünk egyáltalán nincs szükségünk egyetlen másolatra sem, mi csak egyszerűen mozgatgatni akarjuk egy kicsit az a, b, és tmp változókat.
Az új szabvány lehetőséget ad arra, hogy úgynevezett "move constructor"-t, illetve "move assignment"-et definiáljunk, hogy az egyes elemeket másolás helyett mozgassunk.
A fenti példában látható && jelöli az úgynevezett rvalue referenciákat. Ezeket mind bal-, mind jobbértékekhez hozzáköthetjük.
A példához hasonlóan pl s1=s2 esetében használni a move assignment-et lényegében azt jelenti, hogy nem csinálunk egy egy másolatot s2 karaktereiből, hanem ehelyett hagyjuk, hogy s1 a sajátjaiként kezelje azokat, és valahogy töröljük s1 régi karaktereit.
Tekintsük a következő példát:
move(x) jelentése: "úgy használhatod x-et, mintha jobbérték lenne".
A régi void swap(T& a, T& b) továbbra is balértékeket használ, de most, a C++11 lehetőséget ad számunkra a következőkre:
A fenti kóddal felcserélhetünk egy balértéket, és egy jobbértéket.