SlideShare a Scribd company logo
1 of 117
Download to read offline
‹ E ,7FRPPXQLFDWLRQFRP 

1LFRODL 0 -RVXWWLV
,7FRPPXQLFDWLRQFRP

0RGHUQ 

‹ E ,7FRPPXQLFDWLRQFRP 

1LFRODL 0 -RVXWWLV
‡ ,QGHSHQGHQW FRQVXOWDQW
± FRQWLQXRXVO OHDUQLQJ VLQFH 
‡ 6VWHPV $UFKLWHFW 7HFKQLFDO 0DQDJHU
± ILQDQFH PDQXIDFWXULQJ DXWRPRELOH
WHOHFRPPXQLFDWLRQ
‡ 7RSLFV
± 
± 62$ 6HUYLFH 2ULHQWHG $UFKLWHFWXUH
± 7HFKQLFDO 3URMHFW 0DQDJHPHQW
± 3ULYDF FRQWULEXWRU RI (QLJPDLO
Nico Josuttis C++17
@CodeHard 1
‹ E ,7FRPPXQLFDWLRQFRP 

 'LVFODLPHU
‡  LV EUDQG QHZ
± /LPLWHG H[SHULPHQWDO FRPSLOHU VXSSRUW
± :H ZLOO ILQG IODZV LQ 
‡ 7KHVH VOLGHV DUH EUDQG QHZ
± RX ZLOO ILQG IODZV
± 6RPH IHDWXUHV DUH SUREDEO PLVVLQJ
± 6RPH IHDWXUHV DUH QRW ZHOO HQRXJK
GHVFULEHG
± , VWLOO OHDUQ
‡ )HHGEDFN ZHOFRPH
‹ E ,7FRPPXQLFDWLRQFRP 


0RGHUQ 
Nico Josuttis C++17
@CodeHard 2
‹ E ,7FRPPXQLFDWLRQFRP 

 7LPHIUDPH
KWWSLVRFSSRUJVWGVWDWXV
PHGLXP
0RGHUQ 
‹ E ,7FRPPXQLFDWLRQFRP 

 7LPHIUDPH
KWWSLVRFSSRUJVWGVWDWXV
Nico Josuttis C++17
@CodeHard 3
‹ E ,7FRPPXQLFDWLRQFRP 

 6WDQGDUGL]DWLRQ
‡ E ,62
± IRUPDO YRWHV E QDWLRQDO ERGLHV HJ
‡ $16, IRU 86$
‡ ',1 IRU *HUPDQ
‡ (PDLO UHIOHFWRUV IRU GLIIHUHQW ZRUNLQJ DQG VWXG JURXSV
± FRUH OLEUDU FRQFXUUHQF 
‡  RU  MRLQHG PHHWLQJV RI $16, DQG ,62 SHU HDU
± RSHQ WR WKH SXEOLF
‡ (YHUERG LV ZHOFRPH WR
± MRLQ PHHWLQJV
± SURSRVH QHZ IHDWXUHV
± GLVFXVV
‡ ,QIRUPDO ZHE VLWH KWWSLVRFSSRUJVWG
‡ )RUPDO ZHE VLWH KWWSZZZRSHQVWGRUJMWFVFZJ
‹ E ,7FRPPXQLFDWLRQFRP 

 :RUNLQJ DQG 6WXG *URXSV
KWWSLVRFSSRUJVWGWKHFRPPLWWHH
Nico Josuttis C++17
@CodeHard 4
‹ E ,7FRPPXQLFDWLRQFRP 

$YDLODELOLW RI WKH  6WDQGDUG
‡ 'RFXPHQW QXPEHU
± ,62,( 
‡ $YDLODEOH DW QDWLRQV ERGLHV $16, ',1
DQG ,1,76
‡ 3ULFHV YDU
± ,62,(   PHPEHUV
± ',1   ¼
± %6 ,62,(  … PHPEHUV …
± 
‡ 9HUVLRQ FORVH WR ILQDO YHUVLRQ DV GRFXPHQW 1SGI
IRU IUHH DW
± KWWSVZJOLQNQ
‡ KWWSZZZRSHQVWGRUJMWFVFZJGRFVSDSHUVQSGI
‹ E ,7FRPPXQLFDWLRQFRP 

 'RFXPHQWV DQG 3DSHUV
‡ $OO ZRUNLQJ GRFXPHQWV DUH SXEOLF DQG DYDLODEOH
± KWWSVZJOLQN
‡ 'LIIHUHQW SDSHU QXPEHUV VFKHPHV
± 1xxxx
± 3yyyy5 3yyyy5 
‡ ,VVXH /LVWV
± FZJxxx HZJxxx
± OZJxxx OHZJxxx IVxxx
‡ )RU H[DPSOH
± KWWSVZJOLQNQ  GUDIW VWDQGDUG
± KWWSVZJOLQNSU 3URSRVHG ZRUGLQJ IRU 6WUXFWXUHG %LQGLQJV
± KWWSVZJOLQNOZJ ,VVXH IRU std::is_aggregate
Nico Josuttis C++17
@CodeHard 5
‹ E ,7FRPPXQLFDWLRQFRP 

 6XSSRUW
‡ JFFJ 
± VXSSRUWV DOO ODQJXDJH IHDWXUHV
± VXSSRUWV VHYHUDO OLEUDU IHDWXUHV
± 2SWLRQ -std=c++17
‡ ODQJ 
± VXSSRUWV DOO ODQJXDJH IHDWXUHV FODQJ  DQG  PDQ
± 2SWLRQ -std=c++0z RU -std:c++17
‡ 9LVXDO 6WXGLR 
± RPSLOHU YHUVLRQ !  ELQDU FRPSDWLEOH WR 96
± VXSSRUWV VRPH ODQJXDJH IHDWXUHV
± IUHTXHQW XSGDWHV
± 2SWLRQ /std:c++latest RU /std:c++17
‹ E ,7FRPPXQLFDWLRQFRP 

 DQG 9LVXDO 
‡ 9LVXDO 6WXGLR  9LVXDO  DGDSWV  PRUH DQG PRUH
± 6RPH  IHDWXUHV LQ 96
± 0RUH DQG PRUH  IHDWXUHV LQ 96
‡ 96 QRZ KDV FRPSLOHU VZLWFK IRU  6WDQGDUG YHUVLRQ
± /std:c++14 /std:c++17 /std:c++latest
‡ 96 LV ELQDU FRPSDWLEOH WR 96
‡ 96  KDV PXOWLSOH IODYRUV FRPSLOHU YHUVLRQ[
‡ 5HOHDVH FKDQQHO
‡ 96 XSGDWH     VLJQLILFDQWO PRUH
‡ 3UHYLHZ FKDQQHO
‡ 96 XSGDWH  SUHYLHZ  VLQFH 6HS 
‡ 6HH
± KWWSVEORJVPVGQPLFURVRIWFRPYFEORJFIHDWXUHVLQYV
Nico Josuttis C++17
@CodeHard 6
‹ E ,7FRPPXQLFDWLRQFRP 

 ZLWK J
‡ $V RI

‹ E ,7FRPPXQLFDWLRQFRP 

JFODQJ 2QOLQH RPSLOHU
KWWSPHOSRQRUJZDQGER[
XVHV 6HUYHU6LGH (YHQWV
66(
VR RXU ILUHZDOO
VKRXOG QRW EORFN
text/event-stream
Nico Josuttis C++17
@CodeHard 7
‹ E ,7FRPPXQLFDWLRQFRP 

 ZLWK
96
‡ $V RI

 RUH
/LE !
96[
96
‹ E ,7FRPPXQLFDWLRQFRP 

 6XSSRUW E 9LVXDO 6WXGLR  DQG 
‡ 9LVXDO 6WXGLR 
± 6XSSRUW IRU LQFRPSOHWH WSHV LQ YHFWRU OLVW DQG IRUZDUGBOLVW
‡ 9LVXDO 6WXGLR 
± JOREDO VWGVL]H
VWGHPSW
VWGGDWD
± VWGLQYRNH
± VWGXQFDXJKWBH[FHSWLRQV
± VWGERROBFRQVWDQW VWGYRLGBW
‡ 9LVXDO 6WXGLR  8SGDWH 
± JOREDO VWGDVBFRQVW
± 7SH WUDLWV VXIIL[ BY
± VWGVFRSHGBORFN
± IORRU
FHLO
URXQG
DEV
IRU FKURQR!
± 7SH WUDLWV FRQMXQFWLRQ! GLVMXQFWLRQ! QHJDWLRQ!
Nico Josuttis C++17
@CodeHard 8
‹ E ,7FRPPXQLFDWLRQFRP 

/DQJXDJH )HDWXUHV

‹ E ,7FRPPXQLFDWLRQFRP 

 6WUXFWXUHG %LQGLQJV
‡ ,QLWLDOL]H PXOWLSOH LGHQWLILHUVQDPHV IURP
± FODVVVWUXFWXQLRQ REMHFWV
± VWGSDLU! VWGWXSOH! VWGDUUD!
± UDZ DUUDV
‡ 7SHV DUH GHGXFHG IURP PHPEHUVHOHPHQWV
struct MyStruct {
int i;
std::string s;
};
MyStruct ms;

auto [u,v] = ms;  FUHDWH LPSOLFLW HQWLW ZKHUH u v UHSUHVHQW i s
std::cout  u  ' '  SULQW PHPEHUV DVVLJQHG WR XY@
 v  'n';
(TXLYDOHQW WR
auto e = ms;
std::cout  e.i  ' '
 e.s  'n';
Nico Josuttis C++17
@CodeHard 9
‹ E ,7FRPPXQLFDWLRQFRP 

 8VLQJ 6WUXFWXUHG %LQGLQJV
std::mapstd::string, double coll;
 
for (const auto elem : coll) {  HOHPV DUH VWGSDLUFRQVW VWGVWULQJ GRXEOH!
std::cout  elem.first  : 
 elem.second  'n';
}
 VLQFH 
for (const auto [key,val] : coll) {  DFFHVV HOHPV E UHDGRQO UHIHUHQFH
std::cout  key  : 
 val  'n';
}
for (auto [key,val] : coll) {  DFFHVV HOHPV E UHIHUHQFH
if (key != ignore) {
val *= 2;
}
}
‹ E ,7FRPPXQLFDWLRQFRP 

 6WUXFWXUHG %LQGLQJV IRU 5HWXUQ 9DOXHV
struct MyStruct {
int i;
std::string s;
};
MyStruct f1();
auto [u,v] = f1();  XY KDYH WSH DQG YDOXH RI PHPEHUV RI UHWXUQHG REMHFW
auto [w] = f1();  (UURU QXPEHU RI HOHPHQWV GRHV QRW ILW
auto f2() - int()[2];  I
UHWXUQV UHIHUHQFH WR LQW DUUD
auto [x, y] = f2();  [ DQG  DUH intV LQLWLDOL]HG E HOHPV RI UHWXUQHG DUUD
std::arrayint,4 f3();
auto [i,j,k,l] = f3();  LMNO QDPH WKH  HOHPHQWV RI WKH FRSLHG UHWXUQ YDOXH
std::tuplechar,float,std::string f4();
auto [a,b,c] = f4();  DEF KDYH WSHV DQG YDOXHV RI UHWXUQHG WXSOH
Nico Josuttis C++17
@CodeHard 10
‹ E ,7FRPPXQLFDWLRQFRP 

 6WUXFWXUHG %LQGLQJV DQG 4XDOLILHUV
‡ 6WUXFWXUHG ELQGLQJV GHFODUDWLRQ FDQ KDYH WKH XVXDO
TXDOLILHUV  const alignas 
± $OZDV DSSO WR WKH LPSOLFLWO FUHDWHG HQWLW DV D ZKROH
int a[] = { 7, 11 };

auto [ r, s ] = a;  U DQG V DUH LGHQWLILHV WR HOHPHQWV RI D UHIHUHQFH WR D
r = 42;  PRGLI ILUVW HOHPHQW LQ D
std::cout  a[0]  'n';  SULQWV 
struct MyStruct {
std::string name;
int val;
};
MyStruct ms = {Jim, 42};
auto [n,v] = ms;  Q DQG Y DUH HOHPHQWV RI UHIHUHQFH WR PV
std::cout  name:   ms.name  'n';  SULQWV -LP
std::string s = std::move(n);  PRYH PVQDPH WR V
MyStruct f1();
const auto [nm,vl] = f1();  H[WHQGV OLIHWLPH RI UHWXUQHG WHPSRUDU
alignas(16) auto[s,i] = f1();  HQWLW LV EWH DOLJQHG QRW L
‹ E ,7FRPPXQLFDWLRQFRP 

 $GGUHVVHV RI 6WUXFWXUHG %LQGLQJV (OHPHQWV
‡ 6WUXFWXUHG ELQGLQJ GHFODUDWLRQV JXDUDQWHH WKDW WKH REMHFW
ZKRVH PHPEHUV DUH GHQRWHG DUH NHSW WRJHWKHU
auto f() - int ()[2];
auto [x, y] = f();
assert(x + 1 == y);  2.
struct S {  FODVV ZLWK VWDQGDUGODRXW
int no;
double price;
std::string msg;
};
auto [n,p,s] = S{};
assert(((S*)n)-msg == s);  2.
Nico Josuttis C++17
@CodeHard 11
‹ E ,7FRPPXQLFDWLRQFRP 

6WUXFWXUHV %LQGLQJV 0LJKW 1RW 'HFD 0HPEHUV
‡ auto GRHV QRW GHFD VWUXFWXUHG ELQGLQJV
± EHFDXVH LW DSSOLHV WR WKH REMHFW DV D ZKROH
struct S {
int x[3];
int y[3];
};
S s1{};  LQLWLDOL]H DOO PHPEHU DUUDV ZLWK HOHPHQWV EHLQJ 

auto [a, b] = s1;  a DQG b KDYH VDPH PHPEHU WSHV
std::is_samedecltype(a), int[3]::value  LHOGV true
for (int elem : a) {  2. a LV VWLOO DUUD
std::cout  elem  'n';
}
auto p = a;
std::is_samedecltype(p), int*::value  LHOGV true
for (int elem : p) {  (5525 p LV QR DUUD

}
(TXLYDOHQW WR
auto e = s1;
auto a = e.x;
auto b = e.y;
‹ E ,7FRPPXQLFDWLRQFRP 

 6WUXFWXUHG %LQGLQJV YLD 7XSOHOLNH $3,V
class Customer {

public:
std::string getFirst() const { return first; }
std::string getLast() const { return last; }
long getValue() const { return val; }
};
#include utility  IRU WXSOHOLNH $3,
 SURYLGH D WXSOHOLNH $3, IRU FODVV XVWRPHU IRU VWUXFWXUHG ELQGLQJV
template
struct std::tuple_sizeCustomer {
static constexpr int value = 3;  ZH KDYH  DWWULEXWHV
};
template
struct std::tuple_element2, Customer {
using type = long;  ODVW DWWULEXWH LV D ORQJ
};
templatestd::size_t Idx
struct std::tuple_elementIdx, Customer {
using type = std::string;  WKH RWKHU DWWULEXWHV DUH VWULQJV
};
 GHILQH VSHFLILF JHWWHUV
templateint auto get(const Customer c);
template auto get0(const Customer c) { return c.getFirst(); }
template auto get1(const Customer c) { return c.getLast(); }
template auto get2(const Customer c) { return c.getValue(); }
Customer c(Tim, Lee, 42);
auto [f,l,v] = c;
 SULQWV 7LP /HH  
std::cout  f  ' '
 l  : 
 v  'n';
$OO IXOO VSHFLDOL]DWLRQV RI
IXQFWLRQ WHPSODWHV KDYH
WR XVH WKH VDPH VLJQDWXUH
LQFOXGLQJ WKH H[DFW VDPH
UHWXUQ WSH auto
Nico Josuttis C++17
@CodeHard 12
‹ E ,7FRPPXQLFDWLRQFRP 

 if ZLWK ,QLWLDOL]HUV 1HHG 1DPHV
{
std::lock_guardstd::mutex lg(mv);
if (!v.empty()) {
std::cout  v.front()  'n';
}
}
if (std::lock_guardstd::mutex lg(mx); !v.empty()) {  2.
std::cout  v.front()  'n';
}
if (std::lock_guard lg{mx}; !v.empty()) {  2. GXH WR FODVV WHPSODWH DUJ GHGXFWLRQ
std::cout  v.front()  'n';
}
if (std::lock_guardstd::mutex(mx); !v.empty()) {  (5525 ORFN HQGV EHIRUH 
;

std::cout  v.front()  'n';
}
if (std::lock_guard{mx}; !v.empty()) {  (5525 ORFN HQGV EHIRUH 
;

std::cout  v.front()  'n';
}
if (std::lock_guardstd::mutex _(mx); !v.empty()) {  2. EXW
std::cout  v.front()  'n';
}
‹ E ,7FRPPXQLFDWLRQFRP 

 if DQG switch ZLWK ,QLWLDOL]HUV
‡ 1HZ DGGLWLRQDO VQWD[ IRU if DQG switch
if (init; condition)
switch (init; condition)
if (status s = check(); s != status::ok) {
return s;
}
if (std::lock_guardstd::mutex lg(mx);
!v.empty()) {
std::cout  v.front()  'n';
}
switch (Foo gadget(args);
auto s = gadget.status()) {
case OK: gadget.zip(); break;
case Bad: throw BadFoo(s.message());
}
{
status s = check();
if (s != status::ok) {
return s;
}
}
{
std::lock_guardstd::mutex lg(mv);
if (!v.empty()) {
std::cout  v.front()  'n';
}
}
{
Foo gadget(args);
switch (auto s = gadget.status()) {
case OK: gadget.zip(); break;
case Bad: throw BadFoo(s.message());
}
}
Nico Josuttis C++17
@CodeHard 13
‹ E ,7FRPPXQLFDWLRQFRP 

 6WUXFWXUHG %LQGLQJV DQG if ZLWK ,QLWLDOL]HU
‡ RPELQLQJ
± ,QLWLDOL]H PXOWLSOH REMHFWV E PXOWLSOH UHWXUQ YDOXHV
± XVLQJ WKH VXSSOHPHQWDU LQLWLDOL]DWLRQ VQWD[ IRU if
‡ )RU
std::mapstd::string, int coll;
RX FDQ UHSODFH
‡ E
if (auto [pos,ok] = coll.insert({new,42}); !ok) {
 LI LQVHUW IDLOHG KDQGOH HUURU XVLQJ LWHUDWRU pos IRU HOHP DOUHDG WKHUH
const auto [key,val] = *pos;
std::cout  ''  key   exists with key:   val  'n';
}
auto ret = coll.insert({new,42});
if (!ret.second){
 LI LQVHUW IDLOHG SULQW ZK XVLQJ LWHUDWRU ret.first IRU HOHP DOUHDG WKHUH
const auto elem = *(ret.first);
std::cout  ''  elem.first   exists with key: 
 elem.second  'n';
}
2U LQ RQH H[SUHVVLRQ
ret.first-second
‹ E ,7FRPPXQLFDWLRQFRP 

 if ZLWK ,QLWLDOL]HUV 1HHG 1DPHV
‡ $Q WHPSRUDU ZLWKRXW D QDPH LQ WKH LQLWLDOL]DWLRQ
RQO H[LVWV WKHUH QRW LQ WKH ZKROH VWDWHPHQW
‡ 6DPH DV ZLWK for ORRSV
if (std::lock_guardstd::mutex lg(mx); !v.empty()) {  2.
std::cout  v.front()  'n';
}
if (std::lock_guardstd::mutex _(mx); !v.empty()) {  2. EXW
std::cout  v.front()  'n';
}
if (std::lock_guardstd::mutex(mx); !v.empty()) {  (5525 ORFN HQGV EHIRUH 
;

std::cout  v.front()  'n';
}
if (std::lock_guard lg(mx); !v.empty()) {  2. GXH WR FODVV WHPSODWH DUJ GHGXFWLRQ
std::cout  v.front()  'n';
}
Nico Josuttis C++17
@CodeHard 14
‹ E ,7FRPPXQLFDWLRQFRP 

 if ZLWK ,QLWLDOL]HUV 0DNHV +LGGHQ KHFNV 9LVLEOH
‡ %H FDUHIXO ZKHQ FRQYHUWLQJ H[LVWLQJ if ZLWK LQLWLDOL]DWLRQ
‡ 1DLYH PRGLILFDWLRQV WR XVH QHZ IHDWXUH
void f(const Expression* expr)
{
if (const auto* unaryExpr = expr-AsUnaryExpression()) {
if (unaryExpr-Kind() == TokenKind::Plus) {

}
}
}
void f(const Expression* expr)
{
if (const auto* unaryExpr = expr-AsUnaryExpression();
unaryExpr-Kind() == TokenKind::Plus) {

}
}
PLVVLQJ LPSOLFLW
if (unaryExpr)
7KDQNV WR -RQDWKDQ DYHV IRU WKLV H[DPSOH
‹ E ,7FRPPXQLFDWLRQFRP 

 ,QOLQH 9DULDEOHV
‡ 6WDWLF YDULDEOHV PDUNHG ZLWK inline FRXQW DV GHILQLWLRQV
± *XDUDQWHHG WR H[LVW RQO RQFH LQ WKH SURJUDP
± 1R QHHG IRU 33 ILOHV WR GHILQH VWDWLFJOREDO REMHFWV
class Monitor {
public:
Monitor() {  }
void log(const std::string msg) {  }
}
 'HFODUH THE JOREDO PRQLWRU LQ WKH KHDGHU ILOH
  PLJKW EH LQFOXGHG E PXOWLSOH WUDQVODWLRQ XQLWV
inline Monitor progMonitor
PRQLWRUKSS
#include monitor.hpp

progMonitor.log(main());
#include monitor.hpp

progMonitor.log(init());

Nico Josuttis C++17
@CodeHard 15
‹ E ,7FRPPXQLFDWLRQFRP 

 ,QOLQH 9DULDEOHV
‡ 6WDWLF YDULDEOHV PDUNHG ZLWK inline FRXQW DV GHILQLWLRQV
± *XDUDQWHHG WR H[LVW RQO RQFH LQ WKH SURJUDP
‡ HYHQ LI LQFOXGHG PXOWLSOH WLPHV LQ PXOWLSOH WUDQVODWLRQ XQLWV
± 1R QHHG IRU 33 ILOHV WR GHILQH VWDWLFJOREDO REMHFWV
class C
{
private:
static inline bool lg = false;
public:
static void log (bool b) {
lg = b;
}
C() {
if (lg) std::cout  C::C()n;
}

};
#include c.hpp
int main()
{
C::log(true);
C c1;

}
FKSS
#include c.hpp
void foo()
{
C c2;

}
‹ E ,7FRPPXQLFDWLRQFRP 

 $ +HDGHU2QO ::new 7UDFNHU
class TrackNew
{
private:
inline static int numMalloc = 0;  QXPEHU RI QHZ RU QHZ@ FDOOV
inline static long sumSize = 0;  EWHV DOORFDWHG VR IDU
inline static bool doTrace = false;  WUDFLQJ HQDEOHG
public:
static void trace(bool b) {  HQDEOHGLVDEOH WUDFLQJ
doTrace = b;
}
static void status() {  SULQW FXUUHQW VWDWH
std::cerr  numMalloc   mallocs for   sumSize   Bytes  'n';
}
static void* allocate(std::size_t size, const char* call) {  LPSOHPHQWDWLRQ RI WUDFNHG DOORFDWLRQ
++numMalloc;
sumSize += size
if (doTrace) 
return std::malloc(size);
}
};
inline void* operator new (std::size_t size) {
return TrackNew::allocate(size, ::new);
}
inline void* operator new[] (std::size_t size) {
return TrackNew::allocate(size, ::new[]);
}
 LQFOXGLQJ WKH KHDGHU LV HQRXJK
#include tracknew.hpp
int main()
{
 RSWLRQDOO
TrackNew::trace(true);

TrackNew::status();
}
Nico Josuttis C++17
@CodeHard 16
‹ E ,7FRPPXQLFDWLRQFRP 

 ,QOLQH 9DULDEOHV
‡ PLJKW EH LQLWLDOL]HG EHIRUH PDLQ
RU EHIRUH ILUVW XVH
‡ FDQ EH thread_local
‡ constexpr LPSOLHV inline
class Monitor {
public:
Monitor() {  }
void log(const std::string msg) {  }
}
 'HFODUH THE JOREDO PRQLWRU LQ WKH KHDGHU ILOH
  PLJKW EH LQFOXGHG E PXOWLSOH WUDQVODWLRQ XQLWV
inline thread_local Monitor threadLocalMonitor
PRQLWRUKSS
‹ E ,7FRPPXQLFDWLRQFRP 

 static constexpr 'DWD 0HPEHUV DUH inline
‡ 6WDWLF constexpr GDWD PHPEHUV DUH inline VLQFH 
± 'HFODUDWLRQV DUH GHILQLWLRQV
± %HIRUH  WKH GHILQLWLRQV RIWHQ ZHUH QRW QHFHVVDU
‡ 2SWLPL]HG DZD
‡ 'HILQLWLRQ QRW QHHGHG HJ SDVVHG E YDOXH
struct A {
static constexpr int n = 5;   GHFODUDWLRQ
};
std::cout  A::n;  2. ostream::operator(int) JHWV A::n E YDOXH
int inc(const int i);  QRWH WDNHV DUJXPHQW E UHIHUHQFH
std::cout  inc(A::n);  PD IDLO ZLWKRXW GHILQLWLRQ 2. ZLWK JFF ±2 9LVXDO6WXGLR
const int* p = n;  SUREDEO IDLOV ZLWKRXW GHILQLWLRQ 2. ZLWK 9LVXDO6WXGLR
SRVVLEOH GHILQLWLRQ LQ RQH WUDQVODWLRQ XQLW
constexpr int A::n;
Nico Josuttis C++17
@CodeHard 17
‹ E ,7FRPPXQLFDWLRQFRP 

 static constexpr 'DWD 0HPEHUV DUH inline
‡ 6WDWLF constexpr GDWD PHPEHUV DUH inline VLQFH 
± 'HFODUDWLRQV DUH GHILQLWLRQV
± %HIRUH  WKH GHILQLWLRQV RIWHQ ZHUH QRW QHFHVVDU
‡ 2SWLPL]HG DZD
‡ 'HILQLWLRQ QRW QHHGHG HJ SDVVHG E YDOXH
struct A {
static constexpr int n = 5;   GHFODUDWLRQ
 VLQFH  LQOLQH GHILQLWLRQ
};
std::cout  A::n;  2. ostream::operator(int) JHWV A::n E YDOXH
int inc(const int i);  QRWH WDNHV DUJXPHQW E UHIHUHQFH
std::cout  inc(A::n);  PD IDLO ZLWKRXW GHILQLWLRQ 2. ZLWK JFF ±2 9LVXDO6WXGLR
const int* p = n;  SUREDEO IDLOV ZLWKRXW GHILQLWLRQ 2. ZLWK 9LVXDO6WXGLR
SRVVLEOH GHILQLWLRQ LQ RQH WUDQVODWLRQ XQLW
constexpr int A::n;   GHILQLWLRQ
 VLQFH  UHGXQGDQW GHFODUDWLRQ GHSUHFDWHG
‡ $OZDV 2. VLQFH 
‹ E ,7FRPPXQLFDWLRQFRP 

struct Data {
std::string name;
double value;
};
struct Dv : Data {
bool used;
void print() const;
};
Dv u;  2. EXW valuedone ZLWK XQGHILQHG YDOXHV
Dv z{};  2. valuedone ZLWK 0false
bool b = std::is_aggregateAggr::value;  WUXH
Dv x{{item, 6.7}, false};  2. VLQFH 
Dv y{item, 6.7, false};  2. VLQFH  XQOHVV HPSW VXEREMHFWEDVH
%HIRUH  WKLV LV D FODVV
ZLWK LPSOLFLW GHIDXOW FRQVWUXFWRU
6LQFH  WKLV LV D FODVV
WKDW LV DQ DJJUHJDWH
 $JJUHJDWHV ZLWK %DVH ODVVHV
‡ $JJUHJDWHV QRZ FDQ KDYH SXEOLF EDVH FODVVHV
‡ ,QLWLDOL]DWLRQ ZLWK QHVWHG ^` SRVVLEOH
‡ 1HZ WSH WUDLW VWGLVBDJJUHJDWH!
%HIRUH 
struct Dv : Data {
bool used;
Dv (string s, double d, bool b) {
: Data{s,d}, used{b} {
}

};
QHFHVVDU WR HQDEOH
Dv x{hi, 6.7, false};
Nico Josuttis C++17
@CodeHard 18
‹ E ,7FRPPXQLFDWLRQFRP 

 $JJUHJDWH ,QLWLDOL]DWLRQ
‡ /LVW LQLWLDOL]DWLRQ LV ]HUR LQLWLDOL]DWLRQ LI QR YDOXH LV SDVVHG
± 'HIDXOW FRQVWUXFWRU IRU FODVV WSHV
± 0 false nullptr IRU IXQGDPHQWDO GDWD WSHV )'7
struct Data {
std::string name;
double value;
};
struct PData : Data {
bool flag;
};
PData a{{test1, 1.1}, false};  LQLWLDOL]H DOO HOHPHQWV
PData b{test2, 2.2, false};  LQLWLDOL]H DOO HOHPHQWV
PData c{};  VDPH DV {{,0.0},false}
PData d{{msg}};  VDPH DV {{msg,0.0},false}
PData e{{}, true};  VDPH DV {{,0.0},true}
PData f;  QXPHULF HOHPHQWV KDYH XQVSHFLILHG YDOXH
‹ E ,7FRPPXQLFDWLRQFRP 

 $JJUHJDWHV ,QFRPSDWLELOLWLHV
‡ $JJUHJDWHV DUH DUUDV RU FODVV WSHV ZLWK
± QR XVHUGHFODUHG RU H[SOLFLW FRQVWUXFWRU
± QR FRQVWUXFWRU LQKHULWHG E D XVLQJ GHFODUDWLRQ
± QR SULYDWH RU SURWHFWHG QRQVWDWLF GDWD PHPEHUV
± QR YLUWXDO IXQFWLRQV
± QR YLUWXDO SULYDWH RU SURWHFWHG EDVH FODVVHV
‡ $JJUHJDWH LQLWLDOL]DWLRQ PXVW QRW XVH SULYDWH RU SURWHFWHG
EDVH FODVV PHPEHUVFRQVWUXFWRUV
struct Derived;
struct Base {
friend struct Derived;
private:
Base() {  SULYDWH GHIDXOW FRQVWUXFWRU
}
};
struct Derived : Base {
};
Derived d1;  VWLOO 2.
Derived d2{};  (5525 VLQFH 
 1R DJJUHJDWH
 DOOV LPSOLFLW GHIDXOW FRQVWUXFWRU
 $JJUHJDWH
 DOO RI SULYDWH EDVH FRQVWUXFWRU
LV QRW DOORZHG
Nico Josuttis C++17
@CodeHard 19
‹ E ,7FRPPXQLFDWLRQFRP 

 $JJUHJDWHV ,QFRPSDWLELOLWLHV
‡ $JJUHJDWHV DUH DUUDV RU FODVV WSHV ZLWK
± QR XVHUGHFODUHG RU H[SOLFLW FRQVWUXFWRU
± QR FRQVWUXFWRU LQKHULWHG E D XVLQJ GHFODUDWLRQ
± QR SULYDWH RU SURWHFWHG QRQVWDWLF GDWD PHPEHUV
± QR YLUWXDO IXQFWLRQV
± QR YLUWXDO SULYDWH RU SURWHFWHG EDVH FODVVHV
‡ 1RWH $ GHOHWHG GHIDXOW FRQVWUXFWRU GRHVQ
W GLVDEOH
1RWH DJJUHJDWH LQLWLDOL]DWLRQ KWWSVZJOLQNFZJ
struct CData {
int val;
int elems[3];
};
class CppData : public CData {
public:
CppData() = delete;
void print() const;
};
CppData cd1;  (5525
CppData cd2{};  (5525 ZLWK  2. VLQFH
CppData cd3{3, 0, 8, 15};  (5525 ZLWK  2. VLQFH
1R DJJUHJDWH
 RQVWUXFWRU GLVDEOHV DQ
LQLWLDOL]DWLRQ
 $JJUHJDWH
 $JJUHJDWH LQLWLDOL]DWLRQ VWLOO 2.
‹ E ,7FRPPXQLFDWLRQFRP 

 0DQGDWRU 592 DQG RS (OLVLRQ
‡ RS HOLVLRQ IRU LQLWLDOL]DWLRQ IURP WHPSRUDULHV
SUYDOXHV
LV UHTXLUHG VLQFH 
‡ DOODEOH FRSPRYH FRQVWUXFWRU QR ORQJHU UHTXLUHG
class NoCpMv
{
public:
NoCpMv() = default;
 QR FRSPRYH FRQVWUXFWRU
NoCpMv(const NoCpMv) = delete;
NoCpMv(NoCpMv) = delete;

};
void call(NoCpMv obj)
{
}
call(NoCpMv());  2. VLQFH 
 QR FRSPRYH
NoCpMv ret()
{
return NoCpMv();  2. VLQFH 
}  QR FRSPRYH
NoCpMv x = ret();  2. VLQFH 
call(ret());  2. VLQFH 
call(x);  VWLOO (5525
Nico Josuttis C++17
@CodeHard 20
‹ E ,7FRPPXQLFDWLRQFRP 

 %HQHILWV IURP 0DQGDWRU RS (OLVLRQ
‡ 5HTXLUHG FRS HOLVLRQ KHOSV WR
± SURYLGH IDFWRULHV IRU DQ WSH
± GHDOLQJ ZLWK WSHV ZLWK GHOHWHG PRYH
#include utility
 JHQHULF IDFWRU
template typename T, typename... Args
T create(Args... args)
{

return T{std::forwardArgs(args)...};
}
#include atomic
 2. VLQFH 
 1RWH FDQ
W FRSPRYH VWGDWRPLF! REMHFWV
auto ai = createstd::atomicint(42);
class CopyOnly {
public:
CoypeOnly() {
}
CopyOnly(int) {
}
CopyOnly(const CopyOnly) = default;
CopyOnly(CopyOnly) = delete;
};
CopyOnly ret() {
return CopyOnly{};  2. VLQFH 
}
CopyOnly x = 42;  2. VLQFH 
5HPHPEHU
RS FRQVWUXFWRU LV QR IDOOEDFN LI PRYH
FRQVWUXFWRU LV H[SOLFLWO GHOHWHG
‹ E ,7FRPPXQLFDWLRQFRP 

9DOXH DWHJRULHV VLQFH 

(YHU H[SUHVVLRQ LV RQH RI
‡ /9DOXH /RFDOL]DEOH YDOXH
± 9DULDEOH GDWD PHPEHU IXQFWLRQ VWULQJ OLWHUDO UHWXUQHG OYDOXH UHIHUHQFH
± DQ EH RQ WKH OHIW VLGH RI DQ DVVLJQPHQW RQO LI LW
V PRGLILDEOH
‡ 359DOXH 3XUH 59DOXH IRUPHU 59DOXH
± $OO /LWHUDOV H[FHSW VWULQJ OLWHUDOV 42 true nullptr
this ODPEGD UHWXUQHG QRQUHIHUHQFH UHVXOW RI FRQVWUXFWRU FDOO T()
‡ ;9DOXH H;SLULQJ YDOXH
± 5HWXUQHG UYDOXH UHIHUHQFH HJ E VWGPRYH
FDVW WR UYDOXH UHIHUHQFH
*HQHUDO FDWHJRULHV */9DOXH *HQHUDOL]HG /9DOXH 59DOXH JHQHUDOL]HG 59DOXH
H[SUHVVLRQ
UYDOXHJOYDOXH
OYDOXH [YDOXH SUYDOXH
Nico Josuttis C++17
@CodeHard 21
‹ E ,7FRPPXQLFDWLRQFRP 


‡ SUYDOXHV SHUIRUP LQLWLDOL]DWLRQ
± QR WHPSRUDU REMHFW HW
‡ JOYDOXHV SURGXFH ORFDWLRQV
‡ Materialization DV D WHPSRUDU REMHFW
± SUYDOXHWR[YDOXH FRQYHUVLRQ
‡ ZKHQ ERXQG WR D UHIHUHQFH
‡ ZLWK PHPEHU DFFHVV
‡ ZLWK FRQYHUVLRQ WR EDVH
9DOXH DWHJRULHV VLQFH 
MyClass ret() {
return MyClass();  UHWXUQV SUYDOXH QR WHPSRUDU REMHFW HW
}
MyClass x = ret();  XVHV SUYDOXH IRU LQLWLDOL]DWLRQ
void callV(MyClass obj);  DFFHSWV DQ YDOXH FDWHJRU
void callR(const MyClass r);  UHTXLUHV JOYDOXH
void callM(MyClass r);  UHTXLUHV [YDOXH PD EH PDWHULDOL]HG IURP SUYDOXH
callV(ret());  SDVVHV SUYDOXH DQG XVHV LW IRU LQLWLDOL]DWLRQ RI obj
callR(ret());  SDVVHV SUYDOXH PDWHULDOL]HG DV [YDOXH
WR r
callM(ret());  SDVVHV SUYDOXH PDWHULDOL]HG DV [YDOXH
WR r
H[SUHVVLRQ
UYDOXHJOYDOXH
OYDOXH [YDOXH SUYDOXH
temporary
materialization
conversion
‹ E ,7FRPPXQLFDWLRQFRP 

 FRQVWH[SU /DPEGDV
‡ /DPEGDV DUH E GHIDXOW FRQVWH[SU QRZ LI SRVVLEOH
± DQ EH IRUFHG ZLWK FRQVWH[SU
auto squared = [](auto val) {  LPSOLFLWO FRQVWH[SU VLQFH 
return val*val;
};
std::arrayint,squared(5) a;  2. VLQFH  ! VWGDUUDLQW!
auto squared2 = [](auto val) constexpr {  2. VLQFH 
return val*val;
};
auto squared3 = [](auto val) constexpr {  (5525
static int calls=0;  FDQ
W EH FRQVWH[SU GXH WR VWDWLF

return val*val;
};
Nico Josuttis C++17
@CodeHard 22
‹ E ,7FRPPXQLFDWLRQFRP 

/DPEGDV DSWXULQJ this
‡ ,Q PHPEHU IXQFWLRQV FDQ DOVR SDVV this DV FDSWXUH
± LPSOLFLWO GRQH ZLWK [=] DQG []
‡ 6LQFH  *this DOORZV WR SDVV *this E YDOXH
class C
{
private:
std::string name;
public:

void foo() {
 [] { std::cout  name  'n'; }   (UURU
 [] { std::cout  name  'n'; }   2.
 [=] { std::cout  name  'n'; }   2.
 [this] { std::cout  name  'n'; }   2.
 [*this] {std::cout  name  'n'; }   2. VLQFH 
 ORFDO FRS RI 
WKLV
}
};
‹ E ,7FRPPXQLFDWLRQFRP 

 $WWULEXWHV
‡ 1HZ $WWULEXWHV IRUPDO DQQRWDWLRQV
[[ nodiscard ]]
[[ maybe_unused ]]
[[ fallthrough ]]
‡ $WWULEXWHV IRU QDPHVSDFHV DQG HQXPHUDWLRQV
enum E {
foobar = 0,
foobat [[deprecated]] = foobar
};
namespace [[deprecated]] xyz {

}
‡ 8VLQJ GHFODUDWLRQV IRU DWWULEXWHV
[[ using xyz :  ]]
Nico Josuttis C++17
@CodeHard 23
‹ E ,7FRPPXQLFDWLRQFRP 

 1HZ $WWULEXWHV
‡  GHILQHV QHZ $WWULEXWHV IRUPDO DQQRWDWLRQV
[[nodiscard]]
± IRUFH ZDUQLQJ LI UHWXUQ YDOXHV DUH QRW XVHG
± SRUWDEOH [[gnu::warn_unused_result]]
± 3RVVLEOH H[DPSOH
template class F, class... Args
[[nodiscard]] future async(F f, Args... args);
[[ maybe_unused ]]
± GLVDEOHG ZDUQLQJV DERXW QDPHV DQG HQWLWLHV WKDW DUH LQWHQWLRQDOO QRW XVHG
± )RU H[DPSOH
[[maybe_unused]] int y = foo();
[[ fallthrough ]]
± IRU LQWHQWLRQDO VZLWFK caseV KDYLQJ VWDWHPHQWV EXW QR break;
%XW RQO VLQFH 
XVHG LQ WKH OLEUDU
‹ E ,7FRPPXQLFDWLRQFRP 

 1HVWHG 1DPHVSDFH 'HILQLWLRQV
‡ 1HZ VQWD[ IRU QHVWHG QDPHVSDFH GHILQLWLRQV
± ,QVWHDG RI
RX FDQ ZULWH VLQFH 
‡ 1R VXSSRUW IRU QHVWHG LQOLQH QDPHVSDFHV
namespace A {
namespace B {
namespace C {
…
}
}
}
namespace A::B::C {
…
}
)LUVW SURSRVHG
LQ 
Nico Josuttis C++17
@CodeHard 24
‹ E ,7FRPPXQLFDWLRQFRP 

 +HDS $OORFDWLRQ ZLWK $OLJQPHQW
‡ 6LQFH  RSHUDWRU QHZ SURYLGHV DQ LQWHUIDFH WR GHDO
ZLWK DOLJQHG GDWDWSHV
± XVHV LQ std enum class align_val_t : size_t {};
‡ 6HYHUDO QHZ RYHUORDGV IRU RSHUDWRUV
± QHZ QHZ@
± GHOHWH GHOHWH@
new T
 UHVXOWV LQWR FDOOLQJ RQH RI ZKLFKHYHU LV SURYLGHG
operator new(sizeof(T))
operator new(sizeof(T), std::align_val_t(alignof(T)))
new(adr) std::string
 UHVXOWV LQWR FDOOLQJ RQH RI ZKLFKHYHU LV SURYLGHG
operator new(sizeof(std::string), adr)
operator new(sizeof(std::string),
std::align_val_t(alignof(std::string)), adr)
‹ E ,7FRPPXQLFDWLRQFRP 

 ([DPSOH IRU +HDS $OORFDWLRQ ZLWK $OLJQPHQW
#include new  IRU align_val_t
struct alignas(512) Aligned {
int i;
alignas(128) double d;
alignas(512) char c;
 DOORFDWH PHPRU IRU VLQJOH REMHFW ZLWK GHIDXOW DOLJQPHQW
static void* operator new (std::size_t size) {
std::cout  Aligned::new called with size:   size  n;
return ::new char[size];
}
 DOORFDWH PHPRU IRU VLQJOH REMHFW ZLWK H[WHQGHG DOLJQPHQW
static void* operator new (std::size_t size, std::align_val_t align) {
std::cout  Aligned::new called with size:   size
  and align:   static_castint(align)  n;
return ::new char[size];
}
};
Aligned a;  DOLJQHG IRU  DGGUHVV VLQFH
Aligned* ap = new Aligned{};  UHTXHVWV KHDS DOLJQPHQW IRU  DGGUHVV VLQFH 
XVHG DV IDOOEDFN
PD[ LQQHU DOLJQPHQW
IRUFHV RXWHU DOLJQPHQW
VL]HDOLJQ 
LQVWHDG RI HJ
Nico Josuttis C++17
@CodeHard 25
‹ E ,7FRPPXQLFDWLRQFRP 

 _ _has_include
_ _has_include:
‡ 7HVW IRU H[LVWHQFH RI D KHDGHU
‡ +HOSV WR ZULWH SRUWDEOH FRGH
‡ )RU H[DPSOH
#if _ _has_include(optional)
# include optional
# define HAS_OPTIONAL 1
#elif _ _has_include(experimental/optional)
# include experimental/optional
# define HAS_OPTIONAL 1
# define OPTIONAL_IS_EXPERIMENTAL 1
#else
# define HAS_OPTIONAL 0
#endif
‹ E ,7FRPPXQLFDWLRQFRP 

 87) KDUDFWHU /LWHUDOV
‡ (QFRGLQJ SUHIL[ X LHOGV char ZLWK 87) YDOXH
± VLQFH 
‡ L'6' IRU ZFKDUBW OLWHUDOV WZR RU IRXU EWHV QR VSHFLILF FKDUDFWHU VHW
± VLQFH 
‡ u'6' IRU FKDUBW OLWHUDOV WZREWH 87)
‡ U'6' IRU FKDUBW OLWHUDOV IRXUEWH 87)
± VLQFH 
‡ u8'6' IRU 87) FKDUDFWHU OLWHUDOV
± $OUHDG IRU VWULQJ OLWHUDOV VLQFH 
‡ SURYLGHG
± WKH 87) OLWHUDO RQO KDV D VLQJOH FKDUDFWHU
± LWV YDOXH LV UHSUHVHQWDEOH ZLWK D VLQJOH 87) FRGH XQLW
LH LV D 86$6,, FKDUDFWHU
u8'ö'  (5525 WZR EWHVFRGHXQLWV LQ 87)  KH[  %
2QO QHFHVVDU ZKHQ WKH
VRXUFHH[HFXWLRQ FKDUDFWHU VHW
LV QRW 86$6,, HJ FRPSLOLQJ
XQGHU DQ (%', FKDUDFWHU VHW
Nico Josuttis C++17
@CodeHard 26
‹ E ,7FRPPXQLFDWLRQFRP 

 +H[DGHFLPDO )ORDWLQJ3RLQW /LWHUDOV
‡ 0x DOVR IRU IORDWLQJSRLQW OLWHUDOV
± VLJQLILFDQG LV JLYHQ LQ KH[DGHFLPDO
± H[SRQHQW LV JLYHQ LQ GHFLPDO DQG LQWHUSUHWHG ZLWK UHVSHFW WR EDVH 
‡ $V DOUHDG LQ 
‡ $V WKH std::hexfloat LRVWUHDP IRUPDW VLQFH
std::initializer_listdouble values {
0x1p4,  
0xA,  
0xAp2,  
5e0,  
0x1.4p+2,  
1e5,  
0x1.86Ap+16,  
0xC.68p+2,  
};
for (double d : values) {
std::cout  dec:   std::setw(6)  std::defaultfloat  d
  hex:   std::hexfloat  d  'n';
}
2XWSXW
dec: 16 hex: 0x1p+4
dec: 10 hex: 0x1.4p+3
dec: 40 hex: 0x1.4p+5
dec: 5 hex: 0x1.4p+2
dec: 5 hex: 0x1.4p+2
dec: 100000 hex: 0x1.86ap+16
dec: 100000 hex: 0x1.86ap+16
dec: 49.625 hex: 0x1.8dp+5
‹ E ,7FRPPXQLFDWLRQFRP 

 6WDWLFBDVVHUW
ZLWKRXW 0HVVDJHV
‡ VWDWLFBDVVHUW
QR ORQJHU UHTXLUHV WR SDVV D WH[W PHVVDJH
± 3ULQWLQJ D GHIDXOW WH[W PHVVDJH LI DVVHUWLRQ LV YLRODWHG
static_assert(sizeof(int)=4, integers are too small);  2. VLQFH 
static_assert(sizeof(int)=4);  2. VLQFH 
template typename T
class C
{
static_assert(std::is_default_constructibleT::value,
class C: element type T must be default-constructible);
static_assert(std::is_default_constructibleT::value);  2. VLQFH 

};
Nico Josuttis C++17
@CodeHard 27
‹ E ,7FRPPXQLFDWLRQFRP 

7HPSODWH )HDWXUHV

‹ E ,7FRPPXQLFDWLRQFRP 

 0RUH RQYHQLHQFH IRU 7SH 7UDLWV UHWXUQLQJ 9DOXHV
‡ 6LQFH  VKRUWFXWV ZLOO EH SURYLGHG IRU WSH WUDLWV
UHWXUQLQJ YDOXHV
± ,QVWHDG RI
std::is_constT::value
RX FDQ XVH
std::is_const_vT
‡ 7KLV LV GRQH YLD YDULDEOH WHPSODWHV
± DYDLODEOH VLQFH 
namespace std {
template typename T
constexpr bool is_const_v = is_constT::value;
}
Nico Josuttis C++17
@CodeHard 28
‹ E ,7FRPPXQLFDWLRQFRP 

 RPSLOH7LPH if
‡  SURYLGHV D FRPSLOHWLPH LI
± FRQVWH[SU LI
± 7KH then RU else SDUW PD EHFRPH D discarded statement
template typename T
std::string asString(T x)
{
if constexpr(std::is_arithmetic_vT) {
return std::to_string(x);
}
else if constexpr(std::is_same_vT, std::string) {
return x;
}
else {
return std::string(x);
}
}
std::cout  asString(42)  'n';
std::cout  asString(std::string(hello))  'n';
std::cout  asString(hello)  'n';
$OO H[DPSOH FDOOV
ZRXOG EH LQYDOLG
ZKHQ XVLQJ UXQWLPH LI
‹ E ,7FRPPXQLFDWLRQFRP 

 RPSLOH7LPH if ZLWK ,QLWLDOL]HUV
template typename Coll, typename Mutex
void process(const Coll coll, Mutex m)
{

if constexpr (std::lock_guard lg{m};
std::is_pointer_vtypename Coll::value_type) {
  LPSOHPHQW SURFHVVLQJ IRU SRLQWHU HOHPHQWV
}
else {
  LPSOHPHQW SURFHVVLQJ IRU RWKHU HOHPHQWV
}

}
std::vectorint vi;
std::mutex viMutex;

process(vi, viMutex);
std::vectorint* vp;
std::mutex vpMutex;

process(vp, vpMutex);
,QLWLDOL]DWLRQ PLJKW EH
HYDOXDWHG DW UXQWLPH
Nico Josuttis C++17
@CodeHard 29
‹ E ,7FRPPXQLFDWLRQFRP 

 RPSLOH7LPH if 2XWVLGH 7HPSODWHV
‡ if constexpr DOVR FDQ EH XVHG LQ QRQWHPSODWH FRGH
‡ $OO FRGH LQ GLVFDUGHG VWDWHPHQWV PXVW EH YDOLG
template typename T
void foo(T t);
int main()
{
if constexpr(std::numeric_limitschar::is_signed) {
foo(42);  2.
static_assert(std::numeric_limitschar::is_signed,
char is unsigned?);  DOZDV IDLOV LI FKDU LV XQVLJQHG
}
else {
undeclared(42);  DOZDV HUURU LI XQGHFODUHG
QRW GHFODUHG
static_assert(!std::numeric_limitschar::is_signed,
char is signed?);  DOZDV IDLOV LI FKDU LV VLJQHG
}
}
7KLV SURJUDP QHYHU
VXFFHVVIXOO FRPSLOHV
‹ E ,7FRPPXQLFDWLRQFRP 

 RPSLOH7LPH if
‡ 7KH discarded statement PXVW VWLOO EH YDOLG
± 3HUIRUPV WKH ILUVW SKDVH RI WHPSODWH WUDQVODWLRQ GHILQLWLRQ SKDVH
± DOOV QRW GHSHQGLQJ RQ WHPSODWH SDUDPHWHUV DUH LQVWDQWLDWHG
template typename T
void foo(T t)
{
if constexpr(std::is_integral_vT) {
if (t  0) {
foo(t-1);  UHFXUVLYH FDOO 2.
}
}
else {
undeclared();  DOZDV (5525 LI QRW GHFODUHG HYHQ LI GLVFDUGHG
undeclared(t);  (5525 LI QRW GHFODUHG DQG QRW GLVFDUGHG LH T LV QRW LQWHJUDO
static_assert(sizeof(int)4, small int);  PD DVVHUW HYHQ LI GLVFDUGHG
static_assert(sizeof(T)4, small T);  PD DVVHUW RQO LI QRW GLVFDUGHG
}
}
‡ RPSLOHWLPH HUURU
HYHQ LI foo()
QHYHU FDOOHG
 ([FHSW ZLWK 9
Nico Josuttis C++17
@CodeHard 30
‹ E ,7FRPPXQLFDWLRQFRP 

7HPSODWHV 7ZR3KDVH 7UDQVODWLRQ
 :LWKRXW LQVWDQWLDWLRQ DW definition time
± 6QWD[ HUURUV DUH GLVFRYHUHG VXFK DV PLVVLQJ VHPLFRORQV
± )RU FRGH WKDW GRHV QRW GHSHQG RQ WHPSODWH SDUDPHWHUV
‡ XVH RI XQNQRZQ QDPHV WSH QDPHV IXQFWLRQ QDPHV
LV GLVFRYHUHG
‡ VWDWLF DVVHUWLRQV DUH FKHFNHG
 $W instantiation time
± $OO FRGH GHSHQGLQJ RQ WHPSODWH SDUDPHWHUV LV GRXEOHFKHFNHG
templatetypename T
void foo(T t)
{
undeclared();  VW SKDVH HUURU LI undeclared() XQNQRZQ
undeclared(t);  QG SKDVH HUURU LI undeclared(T) XQNQRZQ
static_assert(sizeof(int)4, small int);  VW SKDVH HUURU LI VL]HRILQW
! 
static_assert(sizeof(T)4, small T);  QG SKDVH HUURU LI VL]HRI7
! 
static_assert(false, oops);  DOZDV IDLOV ZKHQ WHPSODWH LV FRPSLOHG HYHQ LI QRW FDOOHG
}
‡  FRPSLOHWLPH HUURUV HYHQ
LI foo() QHYHU FDOOHG
 ([FHSW ZLWK 9
‹ E ,7FRPPXQLFDWLRQFRP 

7HPSODWHV 7ZR3KDVH 7UDQVODWLRQ DQG 9LVXDO 
‡ 9LVXDO  E GHIDXOW
GRHV QR ILUVWSKDVH ORRNXS DW DOO
‡ 9LVXDO 6WXLR  VLQFH
DOORZV ILUVWSKDVH ORRNXS ZLWK
/permissive-
± KWWSVEORJVPVGQPLFURVRIWFRPYFEORJWZRSKDVHQDPHORRNXSVXSSRUWFRPHVWRPVYF
± 8QGHFODUHG IXQFWLRQV DQG static_assert() VWLOO DOZDV LJQRUHG
void func(void*) {
std::cout  calls func(void*) (first-phase lookup)n;
}
templatetypename T
void callfunc(T) {
func(0);  ILUVWSKDVH ORRNXS VKRXOG ILQG RQO func(void*) KHUH
}
void func(int) {
std::cout  calls func(int) (second-phase lookup)n;
}
int main()
{
callfunc(42);  FDOOV IXQFYRLG
ZLWK FRUUHFW WZRSKDVH ORRNXS
}
‡ JFF FODQJ DQG
96 ZLWK /permissive-
 FDOOV func(void*)
VW SKDVH ORRNXS
‡ 96 96 96
ZLWKRXW /permissive-
FDOOV func(int)
QG SKDVH ORRNXS
Nico Josuttis C++17
@CodeHard 31

More Related Content

What's hot

What's hot (18)

Perfil frutas mermela_organica_uk
Perfil frutas mermela_organica_ukPerfil frutas mermela_organica_uk
Perfil frutas mermela_organica_uk
 
5 ( 9 $ 1 8 $ 5 3 urihv
5 ( 9     $ 1 8 $ 5          3 urihv5 ( 9     $ 1 8 $ 5          3 urihv
5 ( 9 $ 1 8 $ 5 3 urihv
 
Teoriaartegotico
TeoriaartegoticoTeoriaartegotico
Teoriaartegotico
 
Amicus brief
Amicus briefAmicus brief
Amicus brief
 
Amicus brief
Amicus briefAmicus brief
Amicus brief
 
Elgriegoenfichas 1bachillerato-sin membrete-1 copia
Elgriegoenfichas 1bachillerato-sin membrete-1 copiaElgriegoenfichas 1bachillerato-sin membrete-1 copia
Elgriegoenfichas 1bachillerato-sin membrete-1 copia
 
Assembly
AssemblyAssembly
Assembly
 
Automatic Configuration of Component-Based Distributed Systems
Automatic Configuration of Component-Based Distributed SystemsAutomatic Configuration of Component-Based Distributed Systems
Automatic Configuration of Component-Based Distributed Systems
 
Manual VRF LG
Manual VRF LGManual VRF LG
Manual VRF LG
 
6th ps 2nd_term_01_chavin
6th ps 2nd_term_01_chavin6th ps 2nd_term_01_chavin
6th ps 2nd_term_01_chavin
 
Misting Systems Catalog 2013 rev beo (anglais)
Misting Systems Catalog 2013 rev beo (anglais)Misting Systems Catalog 2013 rev beo (anglais)
Misting Systems Catalog 2013 rev beo (anglais)
 
Seguridad Computacional
Seguridad ComputacionalSeguridad Computacional
Seguridad Computacional
 
CV
CVCV
CV
 
Mecanismos de falla
Mecanismos de fallaMecanismos de falla
Mecanismos de falla
 
Student Usability in Educational Software and Games: Improving Experiences
Student Usability in Educational Software and Games: Improving ExperiencesStudent Usability in Educational Software and Games: Improving Experiences
Student Usability in Educational Software and Games: Improving Experiences
 
Dr Rahul & Heena Tiwari- How to Write an Article and Publish it - Complete Book
Dr Rahul & Heena Tiwari- How to Write an Article and Publish it - Complete BookDr Rahul & Heena Tiwari- How to Write an Article and Publish it - Complete Book
Dr Rahul & Heena Tiwari- How to Write an Article and Publish it - Complete Book
 
US-40
US-40US-40
US-40
 
Le troisieme testament
Le troisieme testamentLe troisieme testament
Le troisieme testament
 

Similar to Beware of C++17

Pen test pavol.luptak
Pen test pavol.luptakPen test pavol.luptak
Pen test pavol.luptakAmiga Utomo
 
SEO - Optimizacion en buscadores
SEO - Optimizacion en buscadoresSEO - Optimizacion en buscadores
SEO - Optimizacion en buscadoresKanvasMedia
 
Slides clase a_clase
Slides clase a_claseSlides clase a_clase
Slides clase a_clasellorier
 
Pulmonary resection in basrah: personal experience
Pulmonary resection in basrah: personal experiencePulmonary resection in basrah: personal experience
Pulmonary resection in basrah: personal experienceAbdulsalam Taha
 
G2 bsc commissioning manual release b7.2
G2 bsc commissioning manual   release b7.2G2 bsc commissioning manual   release b7.2
G2 bsc commissioning manual release b7.2chungminh1108
 
Hyster D001 (H25XM) Forklift Service Repair Manual.pdf
Hyster D001 (H25XM) Forklift Service Repair Manual.pdfHyster D001 (H25XM) Forklift Service Repair Manual.pdf
Hyster D001 (H25XM) Forklift Service Repair Manual.pdffujsekdmdmd
 
Hyster D001 (H40XMS) Forklift Service Repair Manual.pdf
Hyster D001 (H40XMS) Forklift Service Repair Manual.pdfHyster D001 (H40XMS) Forklift Service Repair Manual.pdf
Hyster D001 (H40XMS) Forklift Service Repair Manual.pdffujsekdmdmd
 
Hyster D001 (H30XM) Forklift Service Repair Manual.pdf
Hyster D001 (H30XM) Forklift Service Repair Manual.pdfHyster D001 (H30XM) Forklift Service Repair Manual.pdf
Hyster D001 (H30XM) Forklift Service Repair Manual.pdffujsekdmdmd
 
Hyster D001 (H35XM) Forklift Service Repair Manual.pdf
Hyster D001 (H35XM) Forklift Service Repair Manual.pdfHyster D001 (H35XM) Forklift Service Repair Manual.pdf
Hyster D001 (H35XM) Forklift Service Repair Manual.pdffujsekdmdmd
 
Published in Nebraska Emerg Mgt Beacon
Published in Nebraska Emerg Mgt BeaconPublished in Nebraska Emerg Mgt Beacon
Published in Nebraska Emerg Mgt Beaconamberalbano
 
New Holland VL660 Grape Harvester Service Repair Manual.pdf
New Holland VL660 Grape Harvester Service Repair Manual.pdfNew Holland VL660 Grape Harvester Service Repair Manual.pdf
New Holland VL660 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VM460 Grape Harvester Service Repair Manual.pdf
New Holland VM460 Grape Harvester Service Repair Manual.pdfNew Holland VM460 Grape Harvester Service Repair Manual.pdf
New Holland VM460 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VL600 Grape Harvester Service Repair Manual.pdf
New Holland VL600 Grape Harvester Service Repair Manual.pdfNew Holland VL600 Grape Harvester Service Repair Manual.pdf
New Holland VL600 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VL640 Grape Harvester Service Repair Manual.pdf
New Holland VL640 Grape Harvester Service Repair Manual.pdfNew Holland VL640 Grape Harvester Service Repair Manual.pdf
New Holland VL640 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VM370 Grape Harvester Service Repair Manual.pdf
New Holland VM370 Grape Harvester Service Repair Manual.pdfNew Holland VM370 Grape Harvester Service Repair Manual.pdf
New Holland VM370 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VL610 Grape Harvester Service Repair Manual.pdf
New Holland VL610 Grape Harvester Service Repair Manual.pdfNew Holland VL610 Grape Harvester Service Repair Manual.pdf
New Holland VL610 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VL620 Grape Harvester Service Repair Manual.pdf
New Holland VL620 Grape Harvester Service Repair Manual.pdfNew Holland VL620 Grape Harvester Service Repair Manual.pdf
New Holland VL620 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 
New Holland VL630 Grape Harvester Service Repair Manual.pdf
New Holland VL630 Grape Harvester Service Repair Manual.pdfNew Holland VL630 Grape Harvester Service Repair Manual.pdf
New Holland VL630 Grape Harvester Service Repair Manual.pdffujsekdmmdm
 

Similar to Beware of C++17 (20)

Pen test pavol.luptak
Pen test pavol.luptakPen test pavol.luptak
Pen test pavol.luptak
 
SEO - Optimizacion en buscadores
SEO - Optimizacion en buscadoresSEO - Optimizacion en buscadores
SEO - Optimizacion en buscadores
 
Slides clase a_clase
Slides clase a_claseSlides clase a_clase
Slides clase a_clase
 
Pulmonary resection in basrah: personal experience
Pulmonary resection in basrah: personal experiencePulmonary resection in basrah: personal experience
Pulmonary resection in basrah: personal experience
 
Insustry
InsustryInsustry
Insustry
 
G2 bsc commissioning manual release b7.2
G2 bsc commissioning manual   release b7.2G2 bsc commissioning manual   release b7.2
G2 bsc commissioning manual release b7.2
 
Pro3100
Pro3100Pro3100
Pro3100
 
Hyster D001 (H25XM) Forklift Service Repair Manual.pdf
Hyster D001 (H25XM) Forklift Service Repair Manual.pdfHyster D001 (H25XM) Forklift Service Repair Manual.pdf
Hyster D001 (H25XM) Forklift Service Repair Manual.pdf
 
Hyster D001 (H40XMS) Forklift Service Repair Manual.pdf
Hyster D001 (H40XMS) Forklift Service Repair Manual.pdfHyster D001 (H40XMS) Forklift Service Repair Manual.pdf
Hyster D001 (H40XMS) Forklift Service Repair Manual.pdf
 
Hyster D001 (H30XM) Forklift Service Repair Manual.pdf
Hyster D001 (H30XM) Forklift Service Repair Manual.pdfHyster D001 (H30XM) Forklift Service Repair Manual.pdf
Hyster D001 (H30XM) Forklift Service Repair Manual.pdf
 
Hyster D001 (H35XM) Forklift Service Repair Manual.pdf
Hyster D001 (H35XM) Forklift Service Repair Manual.pdfHyster D001 (H35XM) Forklift Service Repair Manual.pdf
Hyster D001 (H35XM) Forklift Service Repair Manual.pdf
 
Published in Nebraska Emerg Mgt Beacon
Published in Nebraska Emerg Mgt BeaconPublished in Nebraska Emerg Mgt Beacon
Published in Nebraska Emerg Mgt Beacon
 
New Holland VL660 Grape Harvester Service Repair Manual.pdf
New Holland VL660 Grape Harvester Service Repair Manual.pdfNew Holland VL660 Grape Harvester Service Repair Manual.pdf
New Holland VL660 Grape Harvester Service Repair Manual.pdf
 
New Holland VM460 Grape Harvester Service Repair Manual.pdf
New Holland VM460 Grape Harvester Service Repair Manual.pdfNew Holland VM460 Grape Harvester Service Repair Manual.pdf
New Holland VM460 Grape Harvester Service Repair Manual.pdf
 
New Holland VL600 Grape Harvester Service Repair Manual.pdf
New Holland VL600 Grape Harvester Service Repair Manual.pdfNew Holland VL600 Grape Harvester Service Repair Manual.pdf
New Holland VL600 Grape Harvester Service Repair Manual.pdf
 
New Holland VL640 Grape Harvester Service Repair Manual.pdf
New Holland VL640 Grape Harvester Service Repair Manual.pdfNew Holland VL640 Grape Harvester Service Repair Manual.pdf
New Holland VL640 Grape Harvester Service Repair Manual.pdf
 
New Holland VM370 Grape Harvester Service Repair Manual.pdf
New Holland VM370 Grape Harvester Service Repair Manual.pdfNew Holland VM370 Grape Harvester Service Repair Manual.pdf
New Holland VM370 Grape Harvester Service Repair Manual.pdf
 
New Holland VL610 Grape Harvester Service Repair Manual.pdf
New Holland VL610 Grape Harvester Service Repair Manual.pdfNew Holland VL610 Grape Harvester Service Repair Manual.pdf
New Holland VL610 Grape Harvester Service Repair Manual.pdf
 
New Holland VL620 Grape Harvester Service Repair Manual.pdf
New Holland VL620 Grape Harvester Service Repair Manual.pdfNew Holland VL620 Grape Harvester Service Repair Manual.pdf
New Holland VL620 Grape Harvester Service Repair Manual.pdf
 
New Holland VL630 Grape Harvester Service Repair Manual.pdf
New Holland VL630 Grape Harvester Service Repair Manual.pdfNew Holland VL630 Grape Harvester Service Repair Manual.pdf
New Holland VL630 Grape Harvester Service Repair Manual.pdf
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 

Recently uploaded

Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

Beware of C++17

  • 1. ‹ E ,7FRPPXQLFDWLRQFRP 1LFRODL 0 -RVXWWLV ,7FRPPXQLFDWLRQFRP 0RGHUQ ‹ E ,7FRPPXQLFDWLRQFRP 1LFRODL 0 -RVXWWLV ‡ ,QGHSHQGHQW FRQVXOWDQW ± FRQWLQXRXVO OHDUQLQJ VLQFH ‡ 6VWHPV $UFKLWHFW 7HFKQLFDO 0DQDJHU ± ILQDQFH PDQXIDFWXULQJ DXWRPRELOH WHOHFRPPXQLFDWLRQ ‡ 7RSLFV ± ± 62$ 6HUYLFH 2ULHQWHG $UFKLWHFWXUH
  • 2. ± 7HFKQLFDO 3URMHFW 0DQDJHPHQW ± 3ULYDF FRQWULEXWRU RI (QLJPDLO
  • 4. ‹ E ,7FRPPXQLFDWLRQFRP 'LVFODLPHU ‡ LV EUDQG QHZ ± /LPLWHG H[SHULPHQWDO FRPSLOHU VXSSRUW ± :H ZLOO ILQG IODZV LQ ‡ 7KHVH VOLGHV DUH EUDQG QHZ ± RX ZLOO ILQG IODZV ± 6RPH IHDWXUHV DUH SUREDEO PLVVLQJ ± 6RPH IHDWXUHV DUH QRW ZHOO HQRXJK
  • 5. GHVFULEHG ± , VWLOO OHDUQ ‡ )HHGEDFN ZHOFRPH ‹ E ,7FRPPXQLFDWLRQFRP 0RGHUQ Nico Josuttis C++17 @CodeHard 2
  • 6. ‹ E ,7FRPPXQLFDWLRQFRP 7LPHIUDPH KWWSLVRFSSRUJVWGVWDWXV PHGLXP
  • 7. 0RGHUQ ‹ E ,7FRPPXQLFDWLRQFRP 7LPHIUDPH KWWSLVRFSSRUJVWGVWDWXV Nico Josuttis C++17 @CodeHard 3
  • 8. ‹ E ,7FRPPXQLFDWLRQFRP 6WDQGDUGL]DWLRQ ‡ E ,62 ± IRUPDO YRWHV E QDWLRQDO ERGLHV HJ ‡ $16, IRU 86$ ‡ ',1 IRU *HUPDQ ‡ (PDLO UHIOHFWRUV IRU GLIIHUHQW ZRUNLQJ DQG VWXG JURXSV ± FRUH OLEUDU FRQFXUUHQF ‡ RU MRLQHG PHHWLQJV RI $16, DQG ,62 SHU HDU ± RSHQ WR WKH SXEOLF ‡ (YHUERG LV ZHOFRPH WR ± MRLQ PHHWLQJV ± SURSRVH QHZ IHDWXUHV ± GLVFXVV ‡ ,QIRUPDO ZHE VLWH KWWSLVRFSSRUJVWG ‡ )RUPDO ZHE VLWH KWWSZZZRSHQVWGRUJMWFVFZJ ‹ E ,7FRPPXQLFDWLRQFRP :RUNLQJ DQG 6WXG *URXSV KWWSLVRFSSRUJVWGWKHFRPPLWWHH Nico Josuttis C++17 @CodeHard 4
  • 9. ‹ E ,7FRPPXQLFDWLRQFRP $YDLODELOLW RI WKH 6WDQGDUG ‡ 'RFXPHQW QXPEHU ± ,62,( ‡ $YDLODEOH DW QDWLRQV ERGLHV $16, ',1
  • 10. DQG ,1,76 ‡ 3ULFHV YDU ± ,62,( PHPEHUV
  • 11. ± ',1 ¼ ± %6 ,62,( … PHPEHUV …
  • 12. ± ‡ 9HUVLRQ FORVH WR ILQDO YHUVLRQ DV GRFXPHQW 1SGI IRU IUHH DW ± KWWSVZJOLQNQ ‡ KWWSZZZRSHQVWGRUJMWFVFZJGRFVSDSHUVQSGI ‹ E ,7FRPPXQLFDWLRQFRP 'RFXPHQWV DQG 3DSHUV ‡ $OO ZRUNLQJ GRFXPHQWV DUH SXEOLF DQG DYDLODEOH ± KWWSVZJOLQN ‡ 'LIIHUHQW SDSHU QXPEHUV VFKHPHV ± 1xxxx ± 3yyyy5 3yyyy5 ‡ ,VVXH /LVWV ± FZJxxx HZJxxx ± OZJxxx OHZJxxx IVxxx ‡ )RU H[DPSOH ± KWWSVZJOLQNQ GUDIW VWDQGDUG ± KWWSVZJOLQNSU 3URSRVHG ZRUGLQJ IRU 6WUXFWXUHG %LQGLQJV ± KWWSVZJOLQNOZJ ,VVXH IRU std::is_aggregate Nico Josuttis C++17 @CodeHard 5
  • 13. ‹ E ,7FRPPXQLFDWLRQFRP 6XSSRUW ‡ JFFJ ± VXSSRUWV DOO ODQJXDJH IHDWXUHV ± VXSSRUWV VHYHUDO OLEUDU IHDWXUHV ± 2SWLRQ -std=c++17 ‡ ODQJ ± VXSSRUWV DOO ODQJXDJH IHDWXUHV FODQJ DQG PDQ
  • 14. ± 2SWLRQ -std=c++0z RU -std:c++17 ‡ 9LVXDO 6WXGLR ± RPSLOHU YHUVLRQ ! ELQDU FRPSDWLEOH WR 96
  • 15. ± VXSSRUWV VRPH ODQJXDJH IHDWXUHV ± IUHTXHQW XSGDWHV ± 2SWLRQ /std:c++latest RU /std:c++17 ‹ E ,7FRPPXQLFDWLRQFRP DQG 9LVXDO ‡ 9LVXDO 6WXGLR 9LVXDO DGDSWV PRUH DQG PRUH ± 6RPH IHDWXUHV LQ 96 ± 0RUH DQG PRUH IHDWXUHV LQ 96 ‡ 96 QRZ KDV FRPSLOHU VZLWFK IRU 6WDQGDUG YHUVLRQ ± /std:c++14 /std:c++17 /std:c++latest ‡ 96 LV ELQDU FRPSDWLEOH WR 96 ‡ 96 KDV PXOWLSOH IODYRUV FRPSLOHU YHUVLRQ[
  • 16. ‡ 5HOHDVH FKDQQHO ‡ 96 XSGDWH VLJQLILFDQWO PRUH
  • 17. ‡ 3UHYLHZ FKDQQHO ‡ 96 XSGDWH SUHYLHZ VLQFH 6HS ‡ 6HH ± KWWSVEORJVPVGQPLFURVRIWFRPYFEORJFIHDWXUHVLQYV Nico Josuttis C++17 @CodeHard 6
  • 18. ‹ E ,7FRPPXQLFDWLRQFRP ZLWK J ‡ $V RI ‹ E ,7FRPPXQLFDWLRQFRP JFODQJ 2QOLQH RPSLOHU KWWSPHOSRQRUJZDQGER[ XVHV 6HUYHU6LGH (YHQWV 66(
  • 19. VR RXU ILUHZDOO VKRXOG QRW EORFN text/event-stream Nico Josuttis C++17 @CodeHard 7
  • 20. ‹ E ,7FRPPXQLFDWLRQFRP ZLWK 96 ‡ $V RI RUH /LE ! 96[ 96 ‹ E ,7FRPPXQLFDWLRQFRP 6XSSRUW E 9LVXDO 6WXGLR DQG ‡ 9LVXDO 6WXGLR ± 6XSSRUW IRU LQFRPSOHWH WSHV LQ YHFWRU OLVW DQG IRUZDUGBOLVW ‡ 9LVXDO 6WXGLR ± JOREDO VWGVL]H
  • 25. ± VWGERROBFRQVWDQW VWGYRLGBW ‡ 9LVXDO 6WXGLR 8SGDWH ± JOREDO VWGDVBFRQVW
  • 26. ± 7SH WUDLWV VXIIL[ BY ± VWGVFRSHGBORFN ± IORRU
  • 27. FHLO
  • 28. URXQG
  • 29. DEV
  • 30. IRU FKURQR! ± 7SH WUDLWV FRQMXQFWLRQ! GLVMXQFWLRQ! QHJDWLRQ! Nico Josuttis C++17 @CodeHard 8
  • 31. ‹ E ,7FRPPXQLFDWLRQFRP /DQJXDJH )HDWXUHV ‹ E ,7FRPPXQLFDWLRQFRP 6WUXFWXUHG %LQGLQJV ‡ ,QLWLDOL]H PXOWLSOH LGHQWLILHUVQDPHV IURP ± FODVVVWUXFWXQLRQ REMHFWV ± VWGSDLU! VWGWXSOH! VWGDUUD! ± UDZ DUUDV ‡ 7SHV DUH GHGXFHG IURP PHPEHUVHOHPHQWV struct MyStruct { int i; std::string s; }; MyStruct ms; auto [u,v] = ms; FUHDWH LPSOLFLW HQWLW ZKHUH u v UHSUHVHQW i s std::cout u ' ' SULQW PHPEHUV DVVLJQHG WR XY@ v 'n'; (TXLYDOHQW WR auto e = ms; std::cout e.i ' ' e.s 'n'; Nico Josuttis C++17 @CodeHard 9
  • 32. ‹ E ,7FRPPXQLFDWLRQFRP 8VLQJ 6WUXFWXUHG %LQGLQJV std::mapstd::string, double coll; for (const auto elem : coll) { HOHPV DUH VWGSDLUFRQVW VWGVWULQJ GRXEOH! std::cout elem.first : elem.second 'n'; } VLQFH for (const auto [key,val] : coll) { DFFHVV HOHPV E UHDGRQO UHIHUHQFH std::cout key : val 'n'; } for (auto [key,val] : coll) { DFFHVV HOHPV E UHIHUHQFH if (key != ignore) { val *= 2; } } ‹ E ,7FRPPXQLFDWLRQFRP 6WUXFWXUHG %LQGLQJV IRU 5HWXUQ 9DOXHV struct MyStruct { int i; std::string s; }; MyStruct f1(); auto [u,v] = f1(); XY KDYH WSH DQG YDOXH RI PHPEHUV RI UHWXUQHG REMHFW auto [w] = f1(); (UURU QXPEHU RI HOHPHQWV GRHV QRW ILW auto f2() - int()[2]; I
  • 33. UHWXUQV UHIHUHQFH WR LQW DUUD auto [x, y] = f2(); [ DQG DUH intV LQLWLDOL]HG E HOHPV RI UHWXUQHG DUUD std::arrayint,4 f3(); auto [i,j,k,l] = f3(); LMNO QDPH WKH HOHPHQWV RI WKH FRSLHG UHWXUQ YDOXH std::tuplechar,float,std::string f4(); auto [a,b,c] = f4(); DEF KDYH WSHV DQG YDOXHV RI UHWXUQHG WXSOH Nico Josuttis C++17 @CodeHard 10
  • 34. ‹ E ,7FRPPXQLFDWLRQFRP 6WUXFWXUHG %LQGLQJV DQG 4XDOLILHUV ‡ 6WUXFWXUHG ELQGLQJV GHFODUDWLRQ FDQ KDYH WKH XVXDO TXDOLILHUV const alignas ± $OZDV DSSO WR WKH LPSOLFLWO FUHDWHG HQWLW DV D ZKROH int a[] = { 7, 11 }; auto [ r, s ] = a; U DQG V DUH LGHQWLILHV WR HOHPHQWV RI D UHIHUHQFH WR D r = 42; PRGLI ILUVW HOHPHQW LQ D std::cout a[0] 'n'; SULQWV struct MyStruct { std::string name; int val; }; MyStruct ms = {Jim, 42}; auto [n,v] = ms; Q DQG Y DUH HOHPHQWV RI UHIHUHQFH WR PV std::cout name: ms.name 'n'; SULQWV -LP std::string s = std::move(n); PRYH PVQDPH WR V MyStruct f1(); const auto [nm,vl] = f1(); H[WHQGV OLIHWLPH RI UHWXUQHG WHPSRUDU alignas(16) auto[s,i] = f1(); HQWLW LV EWH DOLJQHG QRW L ‹ E ,7FRPPXQLFDWLRQFRP $GGUHVVHV RI 6WUXFWXUHG %LQGLQJV (OHPHQWV ‡ 6WUXFWXUHG ELQGLQJ GHFODUDWLRQV JXDUDQWHH WKDW WKH REMHFW ZKRVH PHPEHUV DUH GHQRWHG DUH NHSW WRJHWKHU auto f() - int ()[2]; auto [x, y] = f(); assert(x + 1 == y); 2. struct S { FODVV ZLWK VWDQGDUGODRXW int no; double price; std::string msg; }; auto [n,p,s] = S{}; assert(((S*)n)-msg == s); 2. Nico Josuttis C++17 @CodeHard 11
  • 35. ‹ E ,7FRPPXQLFDWLRQFRP 6WUXFWXUHV %LQGLQJV 0LJKW 1RW 'HFD 0HPEHUV ‡ auto GRHV QRW GHFD VWUXFWXUHG ELQGLQJV ± EHFDXVH LW DSSOLHV WR WKH REMHFW DV D ZKROH struct S { int x[3]; int y[3]; }; S s1{}; LQLWLDOL]H DOO PHPEHU DUUDV ZLWK HOHPHQWV EHLQJ auto [a, b] = s1; a DQG b KDYH VDPH PHPEHU WSHV std::is_samedecltype(a), int[3]::value LHOGV true for (int elem : a) { 2. a LV VWLOO DUUD std::cout elem 'n'; } auto p = a; std::is_samedecltype(p), int*::value LHOGV true for (int elem : p) { (5525 p LV QR DUUD } (TXLYDOHQW WR auto e = s1; auto a = e.x; auto b = e.y; ‹ E ,7FRPPXQLFDWLRQFRP 6WUXFWXUHG %LQGLQJV YLD 7XSOHOLNH $3,V class Customer { public: std::string getFirst() const { return first; } std::string getLast() const { return last; } long getValue() const { return val; } }; #include utility IRU WXSOHOLNH $3, SURYLGH D WXSOHOLNH $3, IRU FODVV XVWRPHU IRU VWUXFWXUHG ELQGLQJV template struct std::tuple_sizeCustomer { static constexpr int value = 3; ZH KDYH DWWULEXWHV }; template struct std::tuple_element2, Customer { using type = long; ODVW DWWULEXWH LV D ORQJ }; templatestd::size_t Idx struct std::tuple_elementIdx, Customer { using type = std::string; WKH RWKHU DWWULEXWHV DUH VWULQJV }; GHILQH VSHFLILF JHWWHUV templateint auto get(const Customer c); template auto get0(const Customer c) { return c.getFirst(); } template auto get1(const Customer c) { return c.getLast(); } template auto get2(const Customer c) { return c.getValue(); } Customer c(Tim, Lee, 42); auto [f,l,v] = c; SULQWV 7LP /HH std::cout f ' ' l : v 'n'; $OO IXOO VSHFLDOL]DWLRQV RI IXQFWLRQ WHPSODWHV KDYH WR XVH WKH VDPH VLJQDWXUH LQFOXGLQJ WKH H[DFW VDPH UHWXUQ WSH auto
  • 37. ‹ E ,7FRPPXQLFDWLRQFRP if ZLWK ,QLWLDOL]HUV 1HHG 1DPHV { std::lock_guardstd::mutex lg(mv); if (!v.empty()) { std::cout v.front() 'n'; } } if (std::lock_guardstd::mutex lg(mx); !v.empty()) { 2. std::cout v.front() 'n'; } if (std::lock_guard lg{mx}; !v.empty()) { 2. GXH WR FODVV WHPSODWH DUJ GHGXFWLRQ std::cout v.front() 'n'; } if (std::lock_guardstd::mutex(mx); !v.empty()) { (5525 ORFN HQGV EHIRUH ; std::cout v.front() 'n'; } if (std::lock_guard{mx}; !v.empty()) { (5525 ORFN HQGV EHIRUH ; std::cout v.front() 'n'; } if (std::lock_guardstd::mutex _(mx); !v.empty()) { 2. EXW std::cout v.front() 'n'; } ‹ E ,7FRPPXQLFDWLRQFRP if DQG switch ZLWK ,QLWLDOL]HUV ‡ 1HZ DGGLWLRQDO VQWD[ IRU if DQG switch if (init; condition) switch (init; condition) if (status s = check(); s != status::ok) { return s; } if (std::lock_guardstd::mutex lg(mx); !v.empty()) { std::cout v.front() 'n'; } switch (Foo gadget(args); auto s = gadget.status()) { case OK: gadget.zip(); break; case Bad: throw BadFoo(s.message()); } { status s = check(); if (s != status::ok) { return s; } } { std::lock_guardstd::mutex lg(mv); if (!v.empty()) { std::cout v.front() 'n'; } } { Foo gadget(args); switch (auto s = gadget.status()) { case OK: gadget.zip(); break; case Bad: throw BadFoo(s.message()); } } Nico Josuttis C++17 @CodeHard 13
  • 38. ‹ E ,7FRPPXQLFDWLRQFRP 6WUXFWXUHG %LQGLQJV DQG if ZLWK ,QLWLDOL]HU ‡ RPELQLQJ ± ,QLWLDOL]H PXOWLSOH REMHFWV E PXOWLSOH UHWXUQ YDOXHV ± XVLQJ WKH VXSSOHPHQWDU LQLWLDOL]DWLRQ VQWD[ IRU if ‡ )RU std::mapstd::string, int coll; RX FDQ UHSODFH ‡ E if (auto [pos,ok] = coll.insert({new,42}); !ok) { LI LQVHUW IDLOHG KDQGOH HUURU XVLQJ LWHUDWRU pos IRU HOHP DOUHDG WKHUH
  • 39. const auto [key,val] = *pos; std::cout '' key exists with key: val 'n'; } auto ret = coll.insert({new,42}); if (!ret.second){ LI LQVHUW IDLOHG SULQW ZK XVLQJ LWHUDWRU ret.first IRU HOHP DOUHDG WKHUH
  • 40. const auto elem = *(ret.first); std::cout '' elem.first exists with key: elem.second 'n'; } 2U LQ RQH H[SUHVVLRQ ret.first-second ‹ E ,7FRPPXQLFDWLRQFRP if ZLWK ,QLWLDOL]HUV 1HHG 1DPHV ‡ $Q WHPSRUDU ZLWKRXW D QDPH LQ WKH LQLWLDOL]DWLRQ RQO H[LVWV WKHUH QRW LQ WKH ZKROH VWDWHPHQW ‡ 6DPH DV ZLWK for ORRSV if (std::lock_guardstd::mutex lg(mx); !v.empty()) { 2. std::cout v.front() 'n'; } if (std::lock_guardstd::mutex _(mx); !v.empty()) { 2. EXW std::cout v.front() 'n'; } if (std::lock_guardstd::mutex(mx); !v.empty()) { (5525 ORFN HQGV EHIRUH ; std::cout v.front() 'n'; } if (std::lock_guard lg(mx); !v.empty()) { 2. GXH WR FODVV WHPSODWH DUJ GHGXFWLRQ std::cout v.front() 'n'; } Nico Josuttis C++17 @CodeHard 14
  • 41. ‹ E ,7FRPPXQLFDWLRQFRP if ZLWK ,QLWLDOL]HUV 0DNHV +LGGHQ KHFNV 9LVLEOH ‡ %H FDUHIXO ZKHQ FRQYHUWLQJ H[LVWLQJ if ZLWK LQLWLDOL]DWLRQ ‡ 1DLYH PRGLILFDWLRQV WR XVH QHZ IHDWXUH void f(const Expression* expr) { if (const auto* unaryExpr = expr-AsUnaryExpression()) { if (unaryExpr-Kind() == TokenKind::Plus) { } } } void f(const Expression* expr) { if (const auto* unaryExpr = expr-AsUnaryExpression(); unaryExpr-Kind() == TokenKind::Plus) { } } PLVVLQJ LPSOLFLW if (unaryExpr) 7KDQNV WR -RQDWKDQ DYHV IRU WKLV H[DPSOH ‹ E ,7FRPPXQLFDWLRQFRP ,QOLQH 9DULDEOHV ‡ 6WDWLF YDULDEOHV PDUNHG ZLWK inline FRXQW DV GHILQLWLRQV ± *XDUDQWHHG WR H[LVW RQO RQFH LQ WKH SURJUDP ± 1R QHHG IRU 33 ILOHV WR GHILQH VWDWLFJOREDO REMHFWV class Monitor { public: Monitor() { } void log(const std::string msg) { } } 'HFODUH THE JOREDO PRQLWRU LQ WKH KHDGHU ILOH PLJKW EH LQFOXGHG E PXOWLSOH WUDQVODWLRQ XQLWV inline Monitor progMonitor PRQLWRUKSS #include monitor.hpp progMonitor.log(main()); #include monitor.hpp progMonitor.log(init()); Nico Josuttis C++17 @CodeHard 15
  • 42. ‹ E ,7FRPPXQLFDWLRQFRP ,QOLQH 9DULDEOHV ‡ 6WDWLF YDULDEOHV PDUNHG ZLWK inline FRXQW DV GHILQLWLRQV ± *XDUDQWHHG WR H[LVW RQO RQFH LQ WKH SURJUDP ‡ HYHQ LI LQFOXGHG PXOWLSOH WLPHV LQ PXOWLSOH WUDQVODWLRQ XQLWV ± 1R QHHG IRU 33 ILOHV WR GHILQH VWDWLFJOREDO REMHFWV class C { private: static inline bool lg = false; public: static void log (bool b) { lg = b; } C() { if (lg) std::cout C::C()n; } }; #include c.hpp int main() { C::log(true); C c1; } FKSS #include c.hpp void foo() { C c2; } ‹ E ,7FRPPXQLFDWLRQFRP $ +HDGHU2QO ::new 7UDFNHU class TrackNew { private: inline static int numMalloc = 0; QXPEHU RI QHZ RU QHZ@ FDOOV inline static long sumSize = 0; EWHV DOORFDWHG VR IDU inline static bool doTrace = false; WUDFLQJ HQDEOHG public: static void trace(bool b) { HQDEOHGLVDEOH WUDFLQJ doTrace = b; } static void status() { SULQW FXUUHQW VWDWH std::cerr numMalloc mallocs for sumSize Bytes 'n'; } static void* allocate(std::size_t size, const char* call) { LPSOHPHQWDWLRQ RI WUDFNHG DOORFDWLRQ ++numMalloc; sumSize += size if (doTrace) return std::malloc(size); } }; inline void* operator new (std::size_t size) { return TrackNew::allocate(size, ::new); } inline void* operator new[] (std::size_t size) { return TrackNew::allocate(size, ::new[]); } LQFOXGLQJ WKH KHDGHU LV HQRXJK #include tracknew.hpp int main() { RSWLRQDOO TrackNew::trace(true); TrackNew::status(); } Nico Josuttis C++17 @CodeHard 16
  • 43. ‹ E ,7FRPPXQLFDWLRQFRP ,QOLQH 9DULDEOHV ‡ PLJKW EH LQLWLDOL]HG EHIRUH PDLQ
  • 44. RU EHIRUH ILUVW XVH ‡ FDQ EH thread_local ‡ constexpr LPSOLHV inline class Monitor { public: Monitor() { } void log(const std::string msg) { } } 'HFODUH THE JOREDO PRQLWRU LQ WKH KHDGHU ILOH PLJKW EH LQFOXGHG E PXOWLSOH WUDQVODWLRQ XQLWV inline thread_local Monitor threadLocalMonitor PRQLWRUKSS ‹ E ,7FRPPXQLFDWLRQFRP static constexpr 'DWD 0HPEHUV DUH inline ‡ 6WDWLF constexpr GDWD PHPEHUV DUH inline VLQFH ± 'HFODUDWLRQV DUH GHILQLWLRQV ± %HIRUH WKH GHILQLWLRQV RIWHQ ZHUH QRW QHFHVVDU ‡ 2SWLPL]HG DZD ‡ 'HILQLWLRQ QRW QHHGHG HJ SDVVHG E YDOXH
  • 45. struct A { static constexpr int n = 5; GHFODUDWLRQ }; std::cout A::n; 2. ostream::operator(int) JHWV A::n E YDOXH
  • 46. int inc(const int i); QRWH WDNHV DUJXPHQW E UHIHUHQFH std::cout inc(A::n); PD IDLO ZLWKRXW GHILQLWLRQ 2. ZLWK JFF ±2 9LVXDO6WXGLR
  • 47. const int* p = n; SUREDEO IDLOV ZLWKRXW GHILQLWLRQ 2. ZLWK 9LVXDO6WXGLR
  • 48. SRVVLEOH GHILQLWLRQ LQ RQH WUDQVODWLRQ XQLW
  • 49. constexpr int A::n; Nico Josuttis C++17 @CodeHard 17
  • 50. ‹ E ,7FRPPXQLFDWLRQFRP static constexpr 'DWD 0HPEHUV DUH inline ‡ 6WDWLF constexpr GDWD PHPEHUV DUH inline VLQFH ± 'HFODUDWLRQV DUH GHILQLWLRQV ± %HIRUH WKH GHILQLWLRQV RIWHQ ZHUH QRW QHFHVVDU ‡ 2SWLPL]HG DZD ‡ 'HILQLWLRQ QRW QHHGHG HJ SDVVHG E YDOXH
  • 51. struct A { static constexpr int n = 5; GHFODUDWLRQ VLQFH LQOLQH GHILQLWLRQ }; std::cout A::n; 2. ostream::operator(int) JHWV A::n E YDOXH
  • 52. int inc(const int i); QRWH WDNHV DUJXPHQW E UHIHUHQFH std::cout inc(A::n); PD IDLO ZLWKRXW GHILQLWLRQ 2. ZLWK JFF ±2 9LVXDO6WXGLR
  • 53. const int* p = n; SUREDEO IDLOV ZLWKRXW GHILQLWLRQ 2. ZLWK 9LVXDO6WXGLR
  • 54. SRVVLEOH GHILQLWLRQ LQ RQH WUDQVODWLRQ XQLW
  • 55. constexpr int A::n; GHILQLWLRQ VLQFH UHGXQGDQW GHFODUDWLRQ GHSUHFDWHG
  • 56. ‡ $OZDV 2. VLQFH ‹ E ,7FRPPXQLFDWLRQFRP struct Data { std::string name; double value; }; struct Dv : Data { bool used; void print() const; }; Dv u; 2. EXW valuedone ZLWK XQGHILQHG YDOXHV Dv z{}; 2. valuedone ZLWK 0false bool b = std::is_aggregateAggr::value; WUXH Dv x{{item, 6.7}, false}; 2. VLQFH Dv y{item, 6.7, false}; 2. VLQFH XQOHVV HPSW VXEREMHFWEDVH %HIRUH WKLV LV D FODVV ZLWK LPSOLFLW GHIDXOW FRQVWUXFWRU 6LQFH WKLV LV D FODVV WKDW LV DQ DJJUHJDWH $JJUHJDWHV ZLWK %DVH ODVVHV ‡ $JJUHJDWHV QRZ FDQ KDYH SXEOLF EDVH FODVVHV ‡ ,QLWLDOL]DWLRQ ZLWK QHVWHG ^` SRVVLEOH ‡ 1HZ WSH WUDLW VWGLVBDJJUHJDWH! %HIRUH struct Dv : Data { bool used; Dv (string s, double d, bool b) { : Data{s,d}, used{b} { } }; QHFHVVDU WR HQDEOH Dv x{hi, 6.7, false}; Nico Josuttis C++17 @CodeHard 18
  • 57. ‹ E ,7FRPPXQLFDWLRQFRP $JJUHJDWH ,QLWLDOL]DWLRQ ‡ /LVW LQLWLDOL]DWLRQ LV ]HUR LQLWLDOL]DWLRQ LI QR YDOXH LV SDVVHG ± 'HIDXOW FRQVWUXFWRU IRU FODVV WSHV ± 0 false nullptr IRU IXQGDPHQWDO GDWD WSHV )'7
  • 58. struct Data { std::string name; double value; }; struct PData : Data { bool flag; }; PData a{{test1, 1.1}, false}; LQLWLDOL]H DOO HOHPHQWV PData b{test2, 2.2, false}; LQLWLDOL]H DOO HOHPHQWV PData c{}; VDPH DV {{,0.0},false} PData d{{msg}}; VDPH DV {{msg,0.0},false} PData e{{}, true}; VDPH DV {{,0.0},true} PData f; QXPHULF HOHPHQWV KDYH XQVSHFLILHG YDOXH ‹ E ,7FRPPXQLFDWLRQFRP $JJUHJDWHV ,QFRPSDWLELOLWLHV ‡ $JJUHJDWHV DUH DUUDV RU FODVV WSHV ZLWK ± QR XVHUGHFODUHG RU H[SOLFLW FRQVWUXFWRU ± QR FRQVWUXFWRU LQKHULWHG E D XVLQJ GHFODUDWLRQ ± QR SULYDWH RU SURWHFWHG QRQVWDWLF GDWD PHPEHUV ± QR YLUWXDO IXQFWLRQV ± QR YLUWXDO SULYDWH RU SURWHFWHG EDVH FODVVHV ‡ $JJUHJDWH LQLWLDOL]DWLRQ PXVW QRW XVH SULYDWH RU SURWHFWHG EDVH FODVV PHPEHUVFRQVWUXFWRUV struct Derived; struct Base { friend struct Derived; private: Base() { SULYDWH GHIDXOW FRQVWUXFWRU } }; struct Derived : Base { }; Derived d1; VWLOO 2. Derived d2{}; (5525 VLQFH 1R DJJUHJDWH DOOV LPSOLFLW GHIDXOW FRQVWUXFWRU $JJUHJDWH DOO RI SULYDWH EDVH FRQVWUXFWRU LV QRW DOORZHG Nico Josuttis C++17 @CodeHard 19
  • 59. ‹ E ,7FRPPXQLFDWLRQFRP $JJUHJDWHV ,QFRPSDWLELOLWLHV ‡ $JJUHJDWHV DUH DUUDV RU FODVV WSHV ZLWK ± QR XVHUGHFODUHG RU H[SOLFLW FRQVWUXFWRU ± QR FRQVWUXFWRU LQKHULWHG E D XVLQJ GHFODUDWLRQ ± QR SULYDWH RU SURWHFWHG QRQVWDWLF GDWD PHPEHUV ± QR YLUWXDO IXQFWLRQV ± QR YLUWXDO SULYDWH RU SURWHFWHG EDVH FODVVHV ‡ 1RWH $ GHOHWHG GHIDXOW FRQVWUXFWRU GRHVQ W GLVDEOH 1RWH DJJUHJDWH LQLWLDOL]DWLRQ KWWSVZJOLQNFZJ
  • 60. struct CData { int val; int elems[3]; }; class CppData : public CData { public: CppData() = delete; void print() const; }; CppData cd1; (5525 CppData cd2{}; (5525 ZLWK 2. VLQFH
  • 61. CppData cd3{3, 0, 8, 15}; (5525 ZLWK 2. VLQFH
  • 62. 1R DJJUHJDWH RQVWUXFWRU GLVDEOHV DQ LQLWLDOL]DWLRQ $JJUHJDWH $JJUHJDWH LQLWLDOL]DWLRQ VWLOO 2. ‹ E ,7FRPPXQLFDWLRQFRP 0DQGDWRU 592 DQG RS (OLVLRQ ‡ RS HOLVLRQ IRU LQLWLDOL]DWLRQ IURP WHPSRUDULHV SUYDOXHV
  • 63. LV UHTXLUHG VLQFH ‡ DOODEOH FRSPRYH FRQVWUXFWRU QR ORQJHU UHTXLUHG class NoCpMv { public: NoCpMv() = default; QR FRSPRYH FRQVWUXFWRU NoCpMv(const NoCpMv) = delete; NoCpMv(NoCpMv) = delete; }; void call(NoCpMv obj) { } call(NoCpMv()); 2. VLQFH QR FRSPRYH
  • 64. NoCpMv ret() { return NoCpMv(); 2. VLQFH } QR FRSPRYH
  • 65. NoCpMv x = ret(); 2. VLQFH call(ret()); 2. VLQFH call(x); VWLOO (5525 Nico Josuttis C++17 @CodeHard 20
  • 66. ‹ E ,7FRPPXQLFDWLRQFRP %HQHILWV IURP 0DQGDWRU RS (OLVLRQ ‡ 5HTXLUHG FRS HOLVLRQ KHOSV WR ± SURYLGH IDFWRULHV IRU DQ WSH ± GHDOLQJ ZLWK WSHV ZLWK GHOHWHG PRYH #include utility JHQHULF IDFWRU template typename T, typename... Args T create(Args... args) { return T{std::forwardArgs(args)...}; } #include atomic 2. VLQFH 1RWH FDQ W FRSPRYH VWGDWRPLF! REMHFWV
  • 67. auto ai = createstd::atomicint(42); class CopyOnly { public: CoypeOnly() { } CopyOnly(int) { } CopyOnly(const CopyOnly) = default; CopyOnly(CopyOnly) = delete; }; CopyOnly ret() { return CopyOnly{}; 2. VLQFH } CopyOnly x = 42; 2. VLQFH 5HPHPEHU RS FRQVWUXFWRU LV QR IDOOEDFN LI PRYH FRQVWUXFWRU LV H[SOLFLWO GHOHWHG ‹ E ,7FRPPXQLFDWLRQFRP 9DOXH DWHJRULHV VLQFH (YHU H[SUHVVLRQ LV RQH RI ‡ /9DOXH /RFDOL]DEOH YDOXH ± 9DULDEOH GDWD PHPEHU IXQFWLRQ VWULQJ OLWHUDO UHWXUQHG OYDOXH UHIHUHQFH ± DQ EH RQ WKH OHIW VLGH RI DQ DVVLJQPHQW RQO LI LW V PRGLILDEOH ‡ 359DOXH 3XUH 59DOXH IRUPHU 59DOXH
  • 68. ± $OO /LWHUDOV H[FHSW VWULQJ OLWHUDOV 42 true nullptr
  • 69. this ODPEGD UHWXUQHG QRQUHIHUHQFH UHVXOW RI FRQVWUXFWRU FDOO T()
  • 70. ‡ ;9DOXH H;SLULQJ YDOXH ± 5HWXUQHG UYDOXH UHIHUHQFH HJ E VWGPRYH
  • 71.
  • 72. FDVW WR UYDOXH UHIHUHQFH *HQHUDO FDWHJRULHV */9DOXH *HQHUDOL]HG /9DOXH 59DOXH JHQHUDOL]HG 59DOXH H[SUHVVLRQ UYDOXHJOYDOXH OYDOXH [YDOXH SUYDOXH Nico Josuttis C++17 @CodeHard 21
  • 73. ‹ E ,7FRPPXQLFDWLRQFRP ‡ SUYDOXHV SHUIRUP LQLWLDOL]DWLRQ ± QR WHPSRUDU REMHFW HW ‡ JOYDOXHV SURGXFH ORFDWLRQV ‡ Materialization DV D WHPSRUDU REMHFW ± SUYDOXHWR[YDOXH FRQYHUVLRQ ‡ ZKHQ ERXQG WR D UHIHUHQFH ‡ ZLWK PHPEHU DFFHVV ‡ ZLWK FRQYHUVLRQ WR EDVH 9DOXH DWHJRULHV VLQFH MyClass ret() { return MyClass(); UHWXUQV SUYDOXH QR WHPSRUDU REMHFW HW
  • 74. } MyClass x = ret(); XVHV SUYDOXH IRU LQLWLDOL]DWLRQ void callV(MyClass obj); DFFHSWV DQ YDOXH FDWHJRU void callR(const MyClass r); UHTXLUHV JOYDOXH void callM(MyClass r); UHTXLUHV [YDOXH PD EH PDWHULDOL]HG IURP SUYDOXH
  • 75. callV(ret()); SDVVHV SUYDOXH DQG XVHV LW IRU LQLWLDOL]DWLRQ RI obj callR(ret()); SDVVHV SUYDOXH PDWHULDOL]HG DV [YDOXH
  • 76. WR r callM(ret()); SDVVHV SUYDOXH PDWHULDOL]HG DV [YDOXH
  • 77. WR r H[SUHVVLRQ UYDOXHJOYDOXH OYDOXH [YDOXH SUYDOXH temporary materialization conversion ‹ E ,7FRPPXQLFDWLRQFRP FRQVWH[SU /DPEGDV ‡ /DPEGDV DUH E GHIDXOW FRQVWH[SU QRZ LI SRVVLEOH
  • 78. ± DQ EH IRUFHG ZLWK FRQVWH[SU auto squared = [](auto val) { LPSOLFLWO FRQVWH[SU VLQFH return val*val; }; std::arrayint,squared(5) a; 2. VLQFH ! VWGDUUDLQW! auto squared2 = [](auto val) constexpr { 2. VLQFH return val*val; }; auto squared3 = [](auto val) constexpr { (5525 static int calls=0; FDQ W EH FRQVWH[SU GXH WR VWDWLF return val*val; }; Nico Josuttis C++17 @CodeHard 22
  • 79. ‹ E ,7FRPPXQLFDWLRQFRP /DPEGDV DSWXULQJ this ‡ ,Q PHPEHU IXQFWLRQV FDQ DOVR SDVV this DV FDSWXUH ± LPSOLFLWO GRQH ZLWK [=] DQG [] ‡ 6LQFH *this DOORZV WR SDVV *this E YDOXH class C { private: std::string name; public: void foo() { [] { std::cout name 'n'; } (UURU [] { std::cout name 'n'; } 2. [=] { std::cout name 'n'; } 2. [this] { std::cout name 'n'; } 2. [*this] {std::cout name 'n'; } 2. VLQFH ORFDO FRS RI WKLV } }; ‹ E ,7FRPPXQLFDWLRQFRP $WWULEXWHV ‡ 1HZ $WWULEXWHV IRUPDO DQQRWDWLRQV
  • 80. [[ nodiscard ]] [[ maybe_unused ]] [[ fallthrough ]] ‡ $WWULEXWHV IRU QDPHVSDFHV DQG HQXPHUDWLRQV enum E { foobar = 0, foobat [[deprecated]] = foobar }; namespace [[deprecated]] xyz { } ‡ 8VLQJ GHFODUDWLRQV IRU DWWULEXWHV [[ using xyz : ]] Nico Josuttis C++17 @CodeHard 23
  • 81. ‹ E ,7FRPPXQLFDWLRQFRP 1HZ $WWULEXWHV ‡ GHILQHV QHZ $WWULEXWHV IRUPDO DQQRWDWLRQV
  • 82. [[nodiscard]] ± IRUFH ZDUQLQJ LI UHWXUQ YDOXHV DUH QRW XVHG ± SRUWDEOH [[gnu::warn_unused_result]] ± 3RVVLEOH H[DPSOH template class F, class... Args [[nodiscard]] future async(F f, Args... args); [[ maybe_unused ]] ± GLVDEOHG ZDUQLQJV DERXW QDPHV DQG HQWLWLHV WKDW DUH LQWHQWLRQDOO QRW XVHG ± )RU H[DPSOH [[maybe_unused]] int y = foo(); [[ fallthrough ]] ± IRU LQWHQWLRQDO VZLWFK caseV KDYLQJ VWDWHPHQWV EXW QR break; %XW RQO VLQFH XVHG LQ WKH OLEUDU ‹ E ,7FRPPXQLFDWLRQFRP 1HVWHG 1DPHVSDFH 'HILQLWLRQV ‡ 1HZ VQWD[ IRU QHVWHG QDPHVSDFH GHILQLWLRQV ± ,QVWHDG RI RX FDQ ZULWH VLQFH ‡ 1R VXSSRUW IRU QHVWHG LQOLQH QDPHVSDFHV namespace A { namespace B { namespace C { … } } } namespace A::B::C { … } )LUVW SURSRVHG LQ Nico Josuttis C++17 @CodeHard 24
  • 83. ‹ E ,7FRPPXQLFDWLRQFRP +HDS $OORFDWLRQ ZLWK $OLJQPHQW ‡ 6LQFH RSHUDWRU QHZ SURYLGHV DQ LQWHUIDFH WR GHDO ZLWK DOLJQHG GDWDWSHV ± XVHV LQ std enum class align_val_t : size_t {}; ‡ 6HYHUDO QHZ RYHUORDGV IRU RSHUDWRUV ± QHZ QHZ@ ± GHOHWH GHOHWH@ new T UHVXOWV LQWR FDOOLQJ RQH RI ZKLFKHYHU LV SURYLGHG
  • 84. operator new(sizeof(T)) operator new(sizeof(T), std::align_val_t(alignof(T))) new(adr) std::string UHVXOWV LQWR FDOOLQJ RQH RI ZKLFKHYHU LV SURYLGHG
  • 85. operator new(sizeof(std::string), adr) operator new(sizeof(std::string), std::align_val_t(alignof(std::string)), adr) ‹ E ,7FRPPXQLFDWLRQFRP ([DPSOH IRU +HDS $OORFDWLRQ ZLWK $OLJQPHQW #include new IRU align_val_t struct alignas(512) Aligned { int i; alignas(128) double d; alignas(512) char c; DOORFDWH PHPRU IRU VLQJOH REMHFW ZLWK GHIDXOW DOLJQPHQW static void* operator new (std::size_t size) { std::cout Aligned::new called with size: size n; return ::new char[size]; } DOORFDWH PHPRU IRU VLQJOH REMHFW ZLWK H[WHQGHG DOLJQPHQW static void* operator new (std::size_t size, std::align_val_t align) { std::cout Aligned::new called with size: size and align: static_castint(align) n; return ::new char[size]; } }; Aligned a; DOLJQHG IRU DGGUHVV VLQFH
  • 86. Aligned* ap = new Aligned{}; UHTXHVWV KHDS DOLJQPHQW IRU DGGUHVV VLQFH XVHG DV IDOOEDFN PD[ LQQHU DOLJQPHQW IRUFHV RXWHU DOLJQPHQW VL]HDOLJQ LQVWHDG RI HJ
  • 88. ‹ E ,7FRPPXQLFDWLRQFRP _ _has_include _ _has_include: ‡ 7HVW IRU H[LVWHQFH RI D KHDGHU ‡ +HOSV WR ZULWH SRUWDEOH FRGH ‡ )RU H[DPSOH #if _ _has_include(optional) # include optional # define HAS_OPTIONAL 1 #elif _ _has_include(experimental/optional) # include experimental/optional # define HAS_OPTIONAL 1 # define OPTIONAL_IS_EXPERIMENTAL 1 #else # define HAS_OPTIONAL 0 #endif ‹ E ,7FRPPXQLFDWLRQFRP 87) KDUDFWHU /LWHUDOV ‡ (QFRGLQJ SUHIL[ X LHOGV char ZLWK 87) YDOXH ± VLQFH ‡ L'6' IRU ZFKDUBW OLWHUDOV WZR RU IRXU EWHV QR VSHFLILF FKDUDFWHU VHW
  • 89. ± VLQFH ‡ u'6' IRU FKDUBW OLWHUDOV WZREWH 87)
  • 90. ‡ U'6' IRU FKDUBW OLWHUDOV IRXUEWH 87)
  • 91. ± VLQFH ‡ u8'6' IRU 87) FKDUDFWHU OLWHUDOV ± $OUHDG IRU VWULQJ OLWHUDOV VLQFH ‡ SURYLGHG ± WKH 87) OLWHUDO RQO KDV D VLQJOH FKDUDFWHU ± LWV YDOXH LV UHSUHVHQWDEOH ZLWK D VLQJOH 87) FRGH XQLW LH LV D 86$6,, FKDUDFWHU
  • 92. u8'ö' (5525 WZR EWHVFRGHXQLWV LQ 87) KH[ %
  • 93. 2QO QHFHVVDU ZKHQ WKH VRXUFHH[HFXWLRQ FKDUDFWHU VHW LV QRW 86$6,, HJ FRPSLOLQJ XQGHU DQ (%', FKDUDFWHU VHW
  • 95. ‹ E ,7FRPPXQLFDWLRQFRP +H[DGHFLPDO )ORDWLQJ3RLQW /LWHUDOV ‡ 0x DOVR IRU IORDWLQJSRLQW OLWHUDOV ± VLJQLILFDQG LV JLYHQ LQ KH[DGHFLPDO ± H[SRQHQW LV JLYHQ LQ GHFLPDO DQG LQWHUSUHWHG ZLWK UHVSHFW WR EDVH ‡ $V DOUHDG LQ ‡ $V WKH std::hexfloat LRVWUHDP IRUPDW VLQFH
  • 96. std::initializer_listdouble values { 0x1p4, 0xA, 0xAp2, 5e0, 0x1.4p+2, 1e5, 0x1.86Ap+16, 0xC.68p+2, }; for (double d : values) { std::cout dec: std::setw(6) std::defaultfloat d hex: std::hexfloat d 'n'; } 2XWSXW dec: 16 hex: 0x1p+4 dec: 10 hex: 0x1.4p+3 dec: 40 hex: 0x1.4p+5 dec: 5 hex: 0x1.4p+2 dec: 5 hex: 0x1.4p+2 dec: 100000 hex: 0x1.86ap+16 dec: 100000 hex: 0x1.86ap+16 dec: 49.625 hex: 0x1.8dp+5 ‹ E ,7FRPPXQLFDWLRQFRP 6WDWLFBDVVHUW
  • 98. QR ORQJHU UHTXLUHV WR SDVV D WH[W PHVVDJH ± 3ULQWLQJ D GHIDXOW WH[W PHVVDJH LI DVVHUWLRQ LV YLRODWHG static_assert(sizeof(int)=4, integers are too small); 2. VLQFH static_assert(sizeof(int)=4); 2. VLQFH template typename T class C { static_assert(std::is_default_constructibleT::value, class C: element type T must be default-constructible); static_assert(std::is_default_constructibleT::value); 2. VLQFH }; Nico Josuttis C++17 @CodeHard 27
  • 99. ‹ E ,7FRPPXQLFDWLRQFRP 7HPSODWH )HDWXUHV ‹ E ,7FRPPXQLFDWLRQFRP 0RUH RQYHQLHQFH IRU 7SH 7UDLWV UHWXUQLQJ 9DOXHV ‡ 6LQFH VKRUWFXWV ZLOO EH SURYLGHG IRU WSH WUDLWV UHWXUQLQJ YDOXHV ± ,QVWHDG RI std::is_constT::value RX FDQ XVH std::is_const_vT ‡ 7KLV LV GRQH YLD YDULDEOH WHPSODWHV ± DYDLODEOH VLQFH namespace std { template typename T constexpr bool is_const_v = is_constT::value; } Nico Josuttis C++17 @CodeHard 28
  • 100. ‹ E ,7FRPPXQLFDWLRQFRP RPSLOH7LPH if ‡ SURYLGHV D FRPSLOHWLPH LI ± FRQVWH[SU LI ± 7KH then RU else SDUW PD EHFRPH D discarded statement template typename T std::string asString(T x) { if constexpr(std::is_arithmetic_vT) { return std::to_string(x); } else if constexpr(std::is_same_vT, std::string) { return x; } else { return std::string(x); } } std::cout asString(42) 'n'; std::cout asString(std::string(hello)) 'n'; std::cout asString(hello) 'n'; $OO H[DPSOH FDOOV ZRXOG EH LQYDOLG ZKHQ XVLQJ UXQWLPH LI ‹ E ,7FRPPXQLFDWLRQFRP RPSLOH7LPH if ZLWK ,QLWLDOL]HUV template typename Coll, typename Mutex void process(const Coll coll, Mutex m) { if constexpr (std::lock_guard lg{m}; std::is_pointer_vtypename Coll::value_type) { LPSOHPHQW SURFHVVLQJ IRU SRLQWHU HOHPHQWV } else { LPSOHPHQW SURFHVVLQJ IRU RWKHU HOHPHQWV } } std::vectorint vi; std::mutex viMutex; process(vi, viMutex); std::vectorint* vp; std::mutex vpMutex; process(vp, vpMutex); ,QLWLDOL]DWLRQ PLJKW EH HYDOXDWHG DW UXQWLPH Nico Josuttis C++17 @CodeHard 29
  • 101. ‹ E ,7FRPPXQLFDWLRQFRP RPSLOH7LPH if 2XWVLGH 7HPSODWHV ‡ if constexpr DOVR FDQ EH XVHG LQ QRQWHPSODWH FRGH ‡ $OO FRGH LQ GLVFDUGHG VWDWHPHQWV PXVW EH YDOLG template typename T void foo(T t); int main() { if constexpr(std::numeric_limitschar::is_signed) { foo(42); 2. static_assert(std::numeric_limitschar::is_signed, char is unsigned?); DOZDV IDLOV LI FKDU LV XQVLJQHG } else { undeclared(42); DOZDV HUURU LI XQGHFODUHG
  • 102. QRW GHFODUHG static_assert(!std::numeric_limitschar::is_signed, char is signed?); DOZDV IDLOV LI FKDU LV VLJQHG } } 7KLV SURJUDP QHYHU VXFFHVVIXOO FRPSLOHV ‹ E ,7FRPPXQLFDWLRQFRP RPSLOH7LPH if ‡ 7KH discarded statement PXVW VWLOO EH YDOLG ± 3HUIRUPV WKH ILUVW SKDVH RI WHPSODWH WUDQVODWLRQ GHILQLWLRQ SKDVH
  • 103. ± DOOV QRW GHSHQGLQJ RQ WHPSODWH SDUDPHWHUV DUH LQVWDQWLDWHG template typename T void foo(T t) { if constexpr(std::is_integral_vT) { if (t 0) { foo(t-1); UHFXUVLYH FDOO 2. } } else { undeclared(); DOZDV (5525 LI QRW GHFODUHG HYHQ LI GLVFDUGHG
  • 104. undeclared(t); (5525 LI QRW GHFODUHG DQG QRW GLVFDUGHG LH T LV QRW LQWHJUDO
  • 105. static_assert(sizeof(int)4, small int); PD DVVHUW HYHQ LI GLVFDUGHG static_assert(sizeof(T)4, small T); PD DVVHUW RQO LI QRW GLVFDUGHG } } ‡ RPSLOHWLPH HUURU HYHQ LI foo() QHYHU FDOOHG ([FHSW ZLWK 9 Nico Josuttis C++17 @CodeHard 30
  • 106. ‹ E ,7FRPPXQLFDWLRQFRP 7HPSODWHV 7ZR3KDVH 7UDQVODWLRQ :LWKRXW LQVWDQWLDWLRQ DW definition time ± 6QWD[ HUURUV DUH GLVFRYHUHG VXFK DV PLVVLQJ VHPLFRORQV
  • 107. ± )RU FRGH WKDW GRHV QRW GHSHQG RQ WHPSODWH SDUDPHWHUV ‡ XVH RI XQNQRZQ QDPHV WSH QDPHV IXQFWLRQ QDPHV
  • 108. LV GLVFRYHUHG ‡ VWDWLF DVVHUWLRQV DUH FKHFNHG $W instantiation time ± $OO FRGH GHSHQGLQJ RQ WHPSODWH SDUDPHWHUV LV GRXEOHFKHFNHG templatetypename T void foo(T t) { undeclared(); VW SKDVH HUURU LI undeclared() XQNQRZQ undeclared(t); QG SKDVH HUURU LI undeclared(T) XQNQRZQ static_assert(sizeof(int)4, small int); VW SKDVH HUURU LI VL]HRILQW
  • 109. ! static_assert(sizeof(T)4, small T); QG SKDVH HUURU LI VL]HRI7
  • 110. ! static_assert(false, oops); DOZDV IDLOV ZKHQ WHPSODWH LV FRPSLOHG HYHQ LI QRW FDOOHG
  • 111. } ‡ FRPSLOHWLPH HUURUV HYHQ LI foo() QHYHU FDOOHG ([FHSW ZLWK 9 ‹ E ,7FRPPXQLFDWLRQFRP 7HPSODWHV 7ZR3KDVH 7UDQVODWLRQ DQG 9LVXDO ‡ 9LVXDO E GHIDXOW
  • 112. GRHV QR ILUVWSKDVH ORRNXS DW DOO ‡ 9LVXDO 6WXLR VLQFH
  • 113. DOORZV ILUVWSKDVH ORRNXS ZLWK /permissive- ± KWWSVEORJVPVGQPLFURVRIWFRPYFEORJWZRSKDVHQDPHORRNXSVXSSRUWFRPHVWRPVYF ± 8QGHFODUHG IXQFWLRQV DQG static_assert() VWLOO DOZDV LJQRUHG void func(void*) { std::cout calls func(void*) (first-phase lookup)n; } templatetypename T void callfunc(T) { func(0); ILUVWSKDVH ORRNXS VKRXOG ILQG RQO func(void*) KHUH } void func(int) { std::cout calls func(int) (second-phase lookup)n; } int main() { callfunc(42); FDOOV IXQFYRLG
  • 114. ZLWK FRUUHFW WZRSKDVH ORRNXS } ‡ JFF FODQJ DQG 96 ZLWK /permissive- FDOOV func(void*) VW SKDVH ORRNXS
  • 115. ‡ 96 96 96 ZLWKRXW /permissive-
  • 118. ‹ E ,7FRPPXQLFDWLRQFRP RPSLOH7LPH LI DQG 9DULDGLF 7HPSODWHV template typename T, typename... Types void print (T firstArg, Types... args) { std::cout firstArg 'n'; if (sizeof...(args) 0) { print(args...); (UURU QHHGV SULQW
  • 119. LI sizeof...(args)==0 } } template typename T, typename... Types void print (T firstArg, Types... args) { std::cout firstArg 'n'; if constexpr(sizeof...(args) 0) { VLQFH print(args...); 2. QRW LQVWDQWLDWHG LI sizeof...(args)==0 } } ‹ E ,7FRPPXQLFDWLRQFRP )ROG ([SUHVVLRQV ‡ $SSO ELQDU RSHUDWRUV WR DOO HOHPHQWV RI D SDUDPHWHU SDFN template typename... T auto foldSum1 (T... s){ return (... + s); s1 s2 s3 } template typename... T auto foldSum2 (T... s){ return (0 + ... + s); 0 s1 s2 s3 } auto i = foldSum1(17, 4); auto j = foldSum1(i, 1000, i); foldSum1(hi, hi, hi); (5525 foldSum1(hi, hi, std::string(hi)); (5525 foldSum1(std::string(hi), hi, hi); 2. KLKLKL foldSum1(); (5525 auto i = foldSum2(17, 4); auto j = foldSum2(i, 1000, i); auto k = foldSum2(); foldSum2(std::string(hi), hi, hi); (5525 Nico Josuttis C++17 @CodeHard 32
  • 120. ‹ E ,7FRPPXQLFDWLRQFRP )ROG ([SUHVVLRQV ‡ $SSO ELQDU RSHUDWRUV WR DOO HOHPHQWV RI D SDUDPHWHU SDFN ‡ 6XSSRUWHG VQWD[ (... OP pack) (init OP ... OP pack) (pack OP ...) (pack OP ... OP init) ‡ )RU RSHUDWRUV || DQG , WKH SDFN PLJKW HYHQ EH HPSW ± ,Q WKDW FDVH LHOGV true false void() template typename... T auto foldSum (T... s){ return (... + s); s1 s2 s3 } template typename... T auto foldSum (T... s){ return (0 + ... + s); even works if sizeof...(s)==0 } (( pack1 OP pack2 ) OP pack3 ) ((( init OP pack1 ) OP pack2 ) OP pack3 ) VDPH IURP ULJKW WR OHIW ‹ E ,7FRPPXQLFDWLRQFRP 8VLQJ )ROG ([SUHVVLRQV template typename... Args void printAll (Args... args) { (std::cout ... args) ' '; } templatetypename T void print (T arg) { std::cout arg ' '; } templatetypename T, typename... Types void print (T firstArg, Types... args) { print(firstArg); print(args...); } std::string str = world; print(7.5, hi, str); KL ZRUOG = print(7.5); print(hi, str); = print(7.5); print(hi) print(str); RGH HIIHFWLYHO FRPSLOHG std::string str = world; std::cout hi ' '; std::cout 7.5 ' '; std::cout str ' '; std::string str = world; printAll(7.5, hi, str); KLZRUOG Nico Josuttis C++17 @CodeHard 33
  • 121. ‹ E ,7FRPPXQLFDWLRQFRP 8VLQJ )ROG ([SUHVVLRQV template typename... Args void printAll (Args... args) { (std::cout ... args) ' '; } std::string str = world; printAll(7.5, hi, str); KLZRUOG templatetypename T const T spaceBefore(T arg) { std::cout ' '; return arg; } template typename First, typename... Args void printSpaced(First arg0, Args... args) { std::cout arg0; (std::cout ... spaceBefore(args)) ' '; } std::string str = world; printSpaced(7.5, hi, str); KL ZRUOG ‹ E ,7FRPPXQLFDWLRQFRP )ROG ([SUHVVLRQV IRU )XQFWLRQ DOOV #include iostream struct A { void print() { std::cout An; } }; struct B { void print() { std::cout Bn; } }; struct C { void print() { std::cout Cn; } }; templatetypename... Bases struct MultiBase : private Bases... { void print() { (... , Bases::print()); } }; int main() { MultiBaseA,B,C mb; mb.print(); } H[SDQGV WR A::print(), B::print(), C::print(); Nico Josuttis C++17 @CodeHard 34
  • 122. ‹ E ,7FRPPXQLFDWLRQFRP )ROG ([SUHVVLRQV IRU 0HPEHU 3RLQWHUV GHILQH ELQDU WUHH VWUXFWXUH struct Node { int value; Node* left; Node* right; }; auto left = Node::left; auto right = Node::right; WUDYHUVH WUHH XVLQJ IROG H[SUHVVLRQ template typename T, typename... TP X* traverse (T np, TP... paths){ return (np -* ... -* paths); QS ! SDWKV ! SDWKV } LQLW DQG XVH ELQDU WUHH VWUXFWXUH X* root = new Node{0}; root-left = new Node{1}; root-left-right = new Node{2}; auto p = traverse(root, left, right); ‹ E ,7FRPPXQLFDWLRQFRP )ROG ([SUHVVLRQV IRU 7SHV ‡ )ROG H[SUHVVLRQV FDQ DOVR DSSO WR WSHV templatetypename T1, typename... TN struct IsHomogeneous { static constexpr bool value = (std::is_sameT1,TN::value ...); }; using Size = int; IsHomogeneousint, Size, decltype(42)::value templatetypename T1, typename... TN constexpr bool isHomogeneous(T1, TN...) { return (std::is_sameT1,TN::value ...); } isHomogeneous(43, -1, hello, nullptr) H[SDQGV WR std::is_sameint,Size::value std::is_sameint,decltype(42)::value H[SDQGV WR std::is_sameint,int::value std::is_sameint,const char*::value std::is_sameint,std::nullptr_t::value Nico Josuttis C++17 @CodeHard 35
  • 123. ‹ E ,7FRPPXQLFDWLRQFRP ODVV 7HPSODWH $UJXPHQW 'HGXFWLRQ ‡ ODVV WHPSODWH SDUDPHWHU WSHV FDQ QRZ EH GHGXFHG DFFRUGLQJ WR DUJXPHQWV SDVVHG WR WKH FRQVWUXFWRU templatetypename T class complex; std::cout std::complexint{5,3}; 2. DOO YHUVLRQV std::cout std::complex{5,3}; 2. VLQFH GHGXFHV VWGFRPSOH[LQW! std::cout std::complex(5,3); 2. VLQFH GHGXFHV VWGFRPSOH[LQW! std::cout std::complex(5,3.3); (5525 DUJV GR QRW KDYH WKH VDPH WSH 7 std::mutex mx; std::lock_guard lg(mx); 2. VLQFH GHGXFHV std::lock_guardstd::mutex ‹ E ,7FRPPXQLFDWLRQFRP 1R 3DUWLDO $UJXPHQW 'HGXFWLRQ IRU ODVV 7HPSODWHV ‡ 3DUWLDO FODVV WHPSODWH DUJXPHQW GHGXFWLRQ LV QRW SRVVLEOH ± 6SHFLI DOO RU GHGXFH DOO WHPSODWH SDUDPHWHUV ZLWKRXW GHIDXOWV
  • 124. template typename T1, typename T2, typename T3 = T2 class C { public: C (T1 x = T1{}, T2 y = T2{}, T3 z = T3{}); FRQVWUXFWRU IRU RU DUJXPHQWV }; Cstring,string,int c0; 2. 77 DUH VWULQJ 7 LV LQW Cstring,string,int c1(hi,guy,42); 2. 77 DUH VWULQJ 7 LV LQW Cint,string c2(52,my); 2. 7 LV LQW7 DQG 7 DUH VWULQJV Cstring,string c3(hi,my,guy); 2. 777 DUH VWULQJV Cstring,string c4(hi,my,42); (UURU LV QRW D VWULQJ C c5; (UURU 7 DQG 7 XQGHILQHG C c6(hi); (UURU 7 XQGHILQHG C c7(22,44.3); 2. VLQFH 7 LV LQW 7 DQG 7 DUH GRXEOH C c8(22,44.3,hi); 2. VLQFH 7 LV LQW 7 LV GRXEOH 7 LV FRQVW FKDU C c9(hi,guy); 2. VLQFH 7 7 DQG 7 DUH FRQVW FKDU Cstring c10(hi,my); (UURU RQO 7 H[SOLFLWO GHILQHG C c11(22,44.3); (UURU QHLWKHU 7 QRU 7 H[SOLFLWO GHILQHG C c12(22,44.3,42); (UURU QHLWKHU 7 QRU 7 H[SOLFLWO GHILQHG Nico Josuttis C++17 @CodeHard 36
  • 125. ‹ E ,7FRPPXQLFDWLRQFRP $SSOLQJ $UJXPHQW 'HGXFWLRQ IRU ODVV 7HPSODWHV std::cout std::complex(5,3); 2. VLQFH GHGXFHV D VWGFRPSOH[LQW! std::cout std::complex(5,3.3); (UURU DUJV GR QRW KDYH WKH VDPH WSH std::mutex mx; std::lock_guard lg(mx); 2. VLQFH GHGXFHV std::lock_guardstd::mutex std::tupleint t(42, 43); VWLOO HUURU JRRG
  • 126. FUHDWLQJ VHW ZLWK VSHFLILF VRUWLQJ FULWHULRQ std::setCust coll([](const Cust x, const Cust y) { VWLOO HUURU WRR EDG
  • 127. return x.name() y.name(); }); auto sortcrit = [](const Cust x, const Cust y) { return x.name() y.name(); }; std::setCust, decltype(sortcrit) coll(sortcrit); 2. 0RWLYDWLQJ H[DPSOH DJDLQVW DOORZLQJ SDUWLDO GHGXFWLRQ ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFLQJ 7SH RI /DPEGDV LQ ODVV 7HPSODWHV #include utility IRU std::forward() templatetypename CB class CountCalls { private: CB callback; FDOOEDFN WR FDOO long calls = 0; FRXQWHU IRU FDOOV public: CountCalls(CB cb) : callback(cb) { } templatetypename... Args auto operator() (Args... args) { ++calls; return callback(std::forwardArgs(args)...); } long count() const { return calls; } }; CountCalls sc([](auto x, auto y) { return x y; }); std::sort(v.begin(), v.end(), std::ref(sc)); std::cout sorted with sc.count() callsn; HQDEOHV WR GHGXFH WKH WSH CB RI D SDVVHG ODPEGDIXQFWRU GHGXFHV CountCallsTypeOfLambda Nico Josuttis C++17 @CodeHard 37
  • 128. ‹ E ,7FRPPXQLFDWLRQFRP ODVV 7HPSODWH $UJXPHQW 'HGXFWLRQ RSLHV E 'HIDXOW ‡ ODVV $UJXPHQW 7HPSODWH 'HGXFWLRQ RSLHV E 'HIDXOW ± $IWHU CT x; C{x} GHGXFHV WR CT{x} LQVWHDG RI CCT{x} std::vector v{1, 2, 3}; YHFWRULQW! std::vector a{v}; YHFWRULQW! std::vector b(v); YHFWRULQW! std::vector c = {v}; YHFWRULQW! auto d = std::vector{v}; YHFWRULQW! std::vector v2{v, v}; YHFWRUYHFWRULQW!! LQVWHDG RI YHFWRUYHFWRULQW!! ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV ‡ 'HGXFWLRQ JXLGHV FDQ DGGIL[ GHGXFWLRQV ± 0XVW EH LQ WKH VDPH VFRSH HJ QDPHVSDFH VWG
  • 129. templatetypename T class complex; DV LQ FRPSOH[! std::cout std::complexint{5,3}; 2. DOO YHUVLRQV std::cout std::complex{5,3}; 2. VLQFH GHGXFHV D VWGFRPSOH[LQW! std::cout std::complex(5,3); 2. VLQFH GHGXFHV D VWGFRPSOH[LQW! std::cout std::complex(5,3.3); (UURU DUJV GR QRW KDYH WKH VDPH WSH 7 ,I ZH G KDYH namespace std { templatetypename T1, typename T2 complex(T1,T2) - complexcommon_type_tT1,T2; } WKHQ std::cout std::complex(5,3.3); ZRXOG EH 2. DQG GHGXFH WR VWGFRPSOH[GRXEOH! $ XVHUGHILQHG GHGXFWLRQ JXLGH IRU DQ VWDQGDUG OLEUDU FODVV WHPSODWH UHVXOW LQWR XQGHILQHG EHKDYLRU Nico Josuttis C++17 @CodeHard 38
  • 130. ‹ E ,7FRPPXQLFDWLRQFRP 8VLQJ 'HGXFWLRQ *XLGHV LQ 3UDFWLFH RQVWUXFWRUV ZLWK UHIHUHQFHV ‡ 8VH GHGXFWLRQ JXLGHV WR GHFD WHPSODWH SDUDPHWHU WSHV ± 6WULQJ OLWHUDOV GHGXFH WR SRLQWHU WSHV ‡ 3DUDPHWHUV DUH VWLOO SDVVHG E UHIHUHQFH templatetypename T class MyType { private: T value; public: MyType(const T v) : value{v} { } MyType(T v) : value{std::move(v)} { } }; GHGXFWLRQ JXLGH IRU WKH FRQVWUXFWRUV templatetypename T MyType(T) - MyTypeT; MyType x{hi} HTXLYDOHQW WR MyTypeconst char* x{hi} ‡ (UURU ZLWKRXW GHGXFWLRQ JXLGH ! const char value[3]; ‡ (UURU ZLWK std::decay_tT value; ! char* value; RQVWUXFWRUV VKRXOG PRYH LQLWLDOL]H PHPEHUV IURP EYDOXH SDUDPHWHUV MyType(T v) : value{v} { } ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV ‡ 'HGXFWLRQ JXLGHV ± PD QRW EH WHPSODWHV ± PD QRW FDOO D FRQVWUXFWRU HJ IRU DJJUHJDWHV
  • 131. templatetypename T struct S { T val; }; S(const char*) - Sstd::string; PDS 6! IRU VWULQJ OLWHUDOV WR 6VWGVWULQJ! S s1{hello}; 2. VDPH DV Sstd::string s1{hello}; S s2 = {hello}; 2. VDPH DV Sstd::string s2 = {hello}; S s3 = S{hello}; 2. S s4 = hello; (5525 QR DJJUHJDWH LQLWLDOL]DWLRQ
  • 132. void foo(Sstd::string); foo(S{hello}); 2. VDPH DV foo(Sstd::string{hello}); foo({hello}); 2. GRHV QRW QHHG D GHGXFWLRQ JXLGH foo(hello); (5525 QR DJJUHJDWH LQLWLDOL]DWLRQ
  • 134. ‹ E ,7FRPPXQLFDWLRQFRP ([SOLFLW 'HGXFWLRQ *XLGHV ‡ 'HGXFWLRQ *XLGHV FDQ EH H[SOLFLW ± $IIHFW RQO H[SOLFLW FRQYHUVLRQV ‡ 1R LPSOLFLW FRQYHUVLRQV templatetypename T struct S { T val; }; explicit S(const char*) - Sstd::string; PDS 6! IRU VWULQJ OLWHUDOV WR 6VWGVWULQJ! QRW IRU LPSOLFLW FRQVWUXFWLRQ
  • 135. S s1{hello}; 2. VDPH DV Sstd::string s1{hello}; S s2 = {hello}; (5525 LPSOLFLW FRQYHUVLRQ
  • 136. S s3 = S{hello}; 2. S s4 = {S{hello}}; 2. void foo(Sstd::string); foo(S{hello}); 2. VDPH DV foo(Sstd::string{hello}); foo({hello}); 2. GRHV QRW QHHG D GHGXFWLRQ JXLGH foo(hello); (5525 QR DJJUHJDWH LQLWLDOL]DWLRQ
  • 138. 1R YDOLG DJJUHJDWH LQLWLDOL]DWLRQ (UURU
  • 139. ,QYDOLG QHVWHG LPSOLFLW XVHUGHILQHG FRQYHUVLRQ $JJUHJDWHVODVVHV DQG $UJXPHQW 'HGXFWLRQ (UURU
  • 140. DQ W XVH DUUD DV LQLWLDOL]HU template typename T struct AR { T val; AR(const T s) : val(s) { } }; AR s1(hi); AR s2{hi}; AR s3 = hi; AR s4 = {hi}; ARstd::string s5 = {hi}; AR(const char*) - ARstd::string; AR s1(hi); AR s2{hi}; AR s3 = hi; AR s4 = {hi}; ARstd::string s5 = {hi}; 2. VWULQJ 2. VWULQJ (5525
  • 142. (5525
  • 143. (5525
  • 144. (5525
  • 145. template typename T struct AV { T val; AV(T s) : val(s) { } }; AV s1(hi); AV s2{hi}; AV s3 = hi; AV s4 = {hi}; AVstd::string s5 = {hi}; AV(const char*) - AVstd::string; AV s1(hi); AV s2{hi}; AV s3 = hi; AV s4 = {hi}; AVstd::string s5 = {hi}; 2. FRQVW FKDU 2. FRQVW FKDU 2. FRQVW FKDU 2. FRQVW FKDU 2. VWULQJ 2. VWULQJ (5525
  • 146. 2. VWULQJ template typename T struct A { T val; }; A i1{42}; Aint i2{42}; A s1(hi); A s2{hi}; A s3 = hi; A s4 = {hi}; Astd::string s5 = {hi}; A(const char*) - Astd::string; A s1(hi); A s2{hi}; A s3 = hi; A s4 = {hi}; Astd::string s5 = {hi}; (5525
  • 148. 2. VWULQJ (5525 2. (5525 (5525 (5525 (5525 struct S { S(std::string s); }; S x = hi; (UURU Nico Josuttis C++17 @CodeHard 40
  • 149. ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV LQ WKH /LEUDU ‡ 7R GHFD DQG VXSSRUW PHPEHU WHPSODWHV ± pair tuple optional ‡ 'LVDEOHG IRU SRLQWHUV GXH WR DUUD WSH FODVK
  • 150. ± unique_ptr shared_ptr ‡ FRQYHUVLRQV IURP weak_ptrunique_ptr WR shared_ptr ‡ ,QLWLDOL]H IURP UDQJH ± FRQWDLQHUV H[FHSW array
  • 151. VWULQJV UHJH[ ‡ 2WKHU ± std::array a {42,45,77} ! std::arrayint,3 ± RQWDLQHU DGDSWHUV GHGXFH SDVVHG FRQWDLQHU WSHV ± RSLQJ IRU DOO ORFN JXDUG FODVVHV ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV LQ WKH /LEUDU ‡ 'HGXFWLRQ JXLGHV FDQ DGGIL[ GHGXFWLRQV ‡ 6RPH DUH SUHGHILQHG ‡ )RU H[DPSOH OHW VWGYHFWRU! GHGXFH HOHPHQW WSH IURP LQLWLDOL]LQJ LWHUDWRUV namespace std { templatetypename Iterator vector(Iterator, Iterator) - vectortypename iterator_traitsIterator::value_type; } std::setfloat s; std::vector(s.begin(), s.end()); 2. GHGXFHV std::vectorfloat Nico Josuttis C++17 @CodeHard 41
  • 152. ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV LQ WKH /LEUDU ‡ 'HGXFWLRQ JXLGHV FDQ DGGIL[ GHGXFWLRQV ‡ 6RPH DUH SUHGHILQHG ‡ )RU H[DPSOH OHW VWGDUUD! GHGXFH WKHLU QXPEHU RI HOHPHQWV PXVW KDYH VDPH WSH
  • 153. namespace std { templatetypename T, typename... U array(T, U...) - arrayenable_if_t(is_same_vT,U ...), T, (1 + sizeof...(U)); } std::array a{42,45,77}; 2. GHGXFHV std::arrayint,3 std::array a{42,45,77.7}; (UURU WSHV GLIIHU )ROG ([SUHVVLRQ ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV IRU 6PDUW 3RLQWHUV ‡ make_shared() DQG make_unique() DUH VWLOO XVHIXO ± FODVV WHPSODWH DUJXPHQW GHGXFWLRQ LV QRW HQDEOHG WKHUH ,) :( :28/' +$9( GHGXFWLRQ JXLGH IRU VKDUHG SRLQWHU LQLWLDOL]DWLRQ namespace std{ templatetypename Y shared_ptr(Y*) - shared_ptrY; } std::shared_ptrint sp{new int(7)}; 2. std::shared_ptr sp{new int(7)}; 2. GHGXFHV shared_ptrint std::shared_ptr sp{new int[10]}; 2236 GHGXFHV shared_ptrint namespace std { templatetypename T class shared_ptr { public: constexpr shared_ptr() noexcept; templatetypename Y explicit shared_ptr(Y* p); }; } Nico Josuttis C++17 @CodeHard 42
  • 154. ‹ E ,7FRPPXQLFDWLRQFRP 'HGXFWLRQ *XLGHV 2YHUORDGLQJ ‡ 'HGXFWLRQ JXLGH GHILQH WHPSODWH SDUDPHWHUV ‡ RX FDQ RYHUORDG GHGXFWLRQ JXLGHV templatetypename T struct C { C(T) { } }; templatetypename T C(const T) - Cdouble; templatetypename T C(T) - Clong; templatetypename T C(T) - Cint; C c1(42); GHGXFHV LQW! int x = 42; C c2(x); GHGXFHV ORQJ! C c3(std::move(x)); GHGXFHV LQW! const int c = 42; C c4(c); GHGXFHV GRXEOH! C c5(oops); (5525 FDQ W FRQYHUW FRQVW FKDU@ WR GRXEOH ‹ E ,7FRPPXQLFDWLRQFRP 8VLQJ 'HFODUDWLRQV DUH /LVWV QRZ ‡ 8VLQJ GHFODUDWLRQV FDQ EH OLVWV QRZ ± 6LGH HIIHFW RI SDFN H[SDQVLRQV LQ XVLQJ GHFODUDWLRQV class Base { public: void a(); void b(); void c(); }; class Derived : private Base { public: using Base::a, Base::b, Base::c; }; Derived d; d.a(); d.b(); d.c(); Nico Josuttis C++17 @CodeHard 43
  • 155. ‹ E ,7FRPPXQLFDWLRQFRP 3DFN ([SDQVLRQ LQ using 'HFODUDWLRQV #include string #include unordered_set class Customer { std::string name; public: Customer(const std::string n) : name(n) { } std::string getName() const { return name; } }; struct CustomerEq { bool operator() (const Customer c1, const Customer c2) const { return c1.getName() == c2.getName(); } }; struct CustomerHash { std::size_t operator() (const Customer c) const { return std::hashstd::string()(c.getName()); } }; template typename... Bases struct Overloader : Bases... { using Bases::operator()...; 2. VLQFH }; using CustomerOP = OverloaderCustomerHash,CustomerEq; FRPELQH KDVKHU DQG LQ RQH WSH std::unordered_setCustomer,CustomerHash,CustomerEq coll1; std::unordered_setCustomer,CustomerOP,CustomerOP coll2; ‹ E ,7FRPPXQLFDWLRQFRP ODULILHG ,QKHULWLQJ RQVWUXFWRUV ‡ 6HYHUDO FODULILFDWLRQV RQ LQKHULWLQJ FRQVWUXFWRUV ± using Base::Base ‡ DGRSWV DOO FRQVWUXFWRUV IURP WKH EDVH FODVVHV ‡ RQVWUXFWRUV IRU 7 FDOO ± Base::Base(T) IRU PDWFKLQJ WSH ± Base::Base() IRU RWKHU WSHV ZUDS DQ FODVV E DGRSWLQJ DOO RI LWV FRQVWUXFWRUV ZKLOH ZULWLQJ D PHVVDJH WR WKH VWDQGDUG ORJ ZKHQHYHU DQ REMHFW LV GHVWURHG templatetypename T struct Log : public T { using T::T; LQKHULW DOO FRQVWUXFWRUV IURP FODVV 7 ~Log() { std::clog Destroying wrapper 'n'; } }; Nico Josuttis C++17 @CodeHard 44
  • 156. ‹ E ,7FRPPXQLFDWLRQFRP 9DULDGLF using 'HFODUDWLRQV DQG ,QKHULWHG RQVWUXFWRUV templatetypename T class Base { T value{}; public: Base() { } Base(const T v) : value{v} { } Base operator= (const T v) { value = v; return *this; } }; templatetypename... Types class Multi : private BaseTypes... { public: GHULYH DOO FRQVWUXFWRUV using BaseTypes::Base...; GHULYH DOO DVVLJQPHQW RSHUDWRUV using BaseTypes::operator=...; }; using MultiISP = Multiint,std::string,void*; std::cout std::is_base_of_vBaseint, MultiISP; WUXH MultiISP m1 = 42; MultiISP m2{hello}; 2. HUURU ZLWK MultiISB v2=hello GXH WR WZR XVHUGHILQHG FRQYHUVLRQV
  • 157. MultiISP m3 = nullptr; m3 = 42; 2. ZRXOG DOVR ZRUN ZLWKRXW using operator=...
  • 158. m2 = world; 2. GXH WR using operator=... DOOV ‡ Base::Base(T) IRU PDWFKLQJ WSH ‡ Base::Base() IRU RWKHU WSHV 0XOWL,6% 0XOWLLQWVWGVWULQJERRO!
  • 159. %DVHLQW! %DVHVWGVWULQJ! %DVHERRO! ‹ E ,7FRPPXQLFDWLRQFRP 6WULQJV DV 7HPSODWH $UJXPHQWV ‡ 6LQFH QRQWSH WHPSODWH SDUDPHWHUV FDQ EH LQVWDQWLDWHG ZLWK VWULQJV ZLWK QR OLQNDJH template const char* str class Message { }; extern const char hello[] = Hello World!; H[WHUQDO OLQNDJH const char hello11[] = Hello World!; LQWHUQDO OLQNDJH void foo() { Messagehello msg; 2. DOO YHUVLRQV Messagehello11 msg11; 2. VLQFH static const char hello17[] = Hello World!; QR OLQNDJH Messagehello17 msg17; 2. VLQFH } Nico Josuttis C++17 @CodeHard 45
  • 160. ‹ E ,7FRPPXQLFDWLRQFRP 1RQ7SH 7HPSODWH 3DUDPHWHUV ZLWK auto ‡ 6LQFH RX FDQ GHFODUH QRQWSH WHPSODWH SDUDPHWHUV ZLWK placeholder types auto DQG decltype(auto) template auto N class S { }; S42 s1; 2. WSH RI 1 LQ 6 LV LQW S'a' s2; 2. WSH RI 1 LQ 6 LV FKDU S2.5 s3; (UURU WHPSODWH SDUDPHWHU WSH VWLOO FDQQRW EH GRXEOH SDUWLDO VSHFLDOL]DWLRQ template int N class SN { }; WHPSODWH ZKHUH 3 PXVW EH D SRLQWHU WR FRQVW VRPHWKLQJ template const auto* P struct S; /LVW RI KHWHURJHQHRXV FRQVWDQW WHPSODWH DUJXPHQWV template auto... VS struct value_list { }; /LVW RI KRPRJHQHRXV FRQVWDQW WHPSODWH DUJXPHQWV template auto V1, decltype(V1)... VS struct typed_value_list { }; ‹ E ,7FRPPXQLFDWLRQFRP auto DQG 6WULQJV IRU 1RQ7SH 7HPSODWH 3DUDPHWHUV template auto Msg class Message { public: void print() { std::cout Msg 'n'; } }; int main() { Message'x' m1; m1.print(); RXWSXWV [ Message42 m2; m2.print(); RXWSXWV static const char s[] = hello; Messages m3; 2. VLQFH m3.print(); RXWSXWV KHOOR } Nico Josuttis C++17 @CodeHard 46
  • 161. ‹ E ,7FRPPXQLFDWLRQFRP 8VLQJ )ROG ([SUHVVLRQV ZLWK auto 7HPSODWH 3DUDPHWHUV templateauto sep = ' ', typename First, typename... Args void print(const First arg0, const Args... args) { std::cout arg0; auto coutSepAndArg = [](const auto arg) { std::cout sep arg; }; (... , coutSepAndArg(args)); std::cout 'n'; } std::string str = world; print(7.5, hi, str); KL ZRUOG print'-'(7.5, hi, str); KLZRUOG static const char sep[] = , ; printsep(7.5, hi, str); KL ZRUOG ‹ E ,7FRPPXQLFDWLRQFRP 9DULDEOH 7HPSODWHV ZLWK auto #include variable.hpp #include iostream void print() { std::cout arrdouble,100u 'n'; std::cout arrint,10 'n'; for (unsigned i=0; iarrint,10.size(); ++i) { std::cout arrint,10[i] 'n'; } } #include variable.hpp void print(); int main() { arrdouble,100u[0] = 17; arrint,10[0] = 42; print(); std::cout val'c' 'n'; } #include array templatetypename T, auto N std::arrayT,N arr; 2. VLQFH templateauto N constexpr decltype(N) val = N; 2. VLQFH WZR GLIIHUHQW JOREDO REMHFWV arr XVHG LQ ERWK WUDQVODWLRQ XQLWV WZR GLIIHUHQW JOREDO REMHFWV arr XVHG LQ ERWK WUDQVODWLRQ XQLWV Nico Josuttis C++17 @CodeHard 47
  • 162. ‹ E ,7FRPPXQLFDWLRQFRP 1RQ7SH 7HPSODWH 3DUDPHWHUV ZLWK decltype(auto) #include iostream #include type_traits templatedecltype(auto) N struct S { S() { if (std::is_same_vdecltype(N),int) std::cout ref ; std::cout N has value N 'n'; } void print() { std::cout value: N 'n'; } }; constexpr int x = 42; int y = 0; OYDOXH int main() { Sx s0; 1 LV LQW ! SULQWV N has value 42 S(y) s1; 1 LV LQW ! SULQWV ref N has value 0 y = 77; S(y) s2; 1 LV LQW ! SULQWV ref N has value 77 y = 88; s1.print(); SULQWV value: 88 s2.print(); SULQWV value: 88 } 5HPHPEHU decltype(auto) XVHV WKH UXOHV RI decltype WSH RI HQWLW H YDOXH FDWHJRU RI H[SUHVVLRQ H IRU SUYDOXHV type IRU OYDOXHV type IRU [YDOXHV type ‹ E ,7FRPPXQLFDWLRQFRP RUH )L[HV DQG ,PSURYHPHQWV Nico Josuttis C++17 @CodeHard 48
  • 163. ‹ E ,7FRPPXQLFDWLRQFRP JXDUDQWHHG VLQFH 'HILQHG ([SUHVVLRQ (YDOXDWLRQ 2UGHU ‡ 0RVW RSHUDWRUV KDYH QR GHILQHG HYDOXDWLRQ RUGHU VLQFH std::string s = I heard it even works if you don't believe; s.replace(0,8,).replace(s.find(even),4,sometimes) .replace(s.find(you don't),9,I); it sometimes works if I believe it sometimes workIdon't believe SRVVLEOH EHIRUH it even worsometiIdon't believe SRVVLEOH EHIRUH it even worsometimesf youIlieve SRVVLEOH EHIRUH DOVR XQGHILQHG EHKDYLRU LI I
  • 164. J
  • 166. GHSHQG RQ HDFK RWKHU std::cout f() g() h(); FDOOV cout.operator(f()) FDOOV cout.operator(g()).operator(h()); ‡ GHILQHV HYDOXDWLRQ RUGHU IRU . - .* -* = += -= [] expr(a,b,c) ± expr EHIRUH a DQG b DQG c EXW abc VWLOO LQ DQ RUGHU ‹ E ,7FRPPXQLFDWLRQFRP 'HILQHG ([SUHVVLRQ (YDOXDWLRQ 2UGHU ‡ GHILQHV HYDOXDWLRQ RUGHU RI . - .* -* = += -= [] f(a,b,c) ± )RU f(a,b,c): f EHIRUH a/b/c EXW abc VWLOO LQ DQ RUGHU DQ DQDQVW QG UG s.replace(0,4,).replace(s.find(even),4,only).replace(s.find( don't),6,);s.replace(0,4,).replace(s.find(even),4,only).replace(s.find( don't),6,);s.replace(0,4,).replace(s.find(even),4,only).replace(s.find( don't),6,);s.replace(0,4,).replace(s.find(even),4,only).replace(s.find( don't),6,);s.replace(0,4,).replace(s.find(even),4,only).replace(s.find( don't),6,);s.replace(0,4,).replace(s.find(even),4,only).replace(s.find( don't),6,); std::string s = but I have heard it works even if you don’t believe; s.replace(0,4,).replace(s.find(even),4,only) .replace(s.find( don't),6,); LV QRZ HYDOXDWHG DV IROORZV Nico Josuttis C++17 @CodeHard 49
  • 167. ‹ E ,7FRPPXQLFDWLRQFRP 'HILQHG ([SUHVVLRQ (YDOXDWLRQ 2UGHU RQVHTXHQFHV void printElem(const std::vectorint v, int idx, const std::string pre = ) { std::cout pre v.at(idx) 'n'; PLJKW WKURZ VWGRXWBRIBUDQJH } try { std::vectorint coll{7, 14, 21, 28}; for (int i=0; i=coll.size(); ++i) { printElem(coll, i, elem: ); } } catch (const std::exception e) { std::cerr EXCEPTION: e.what() 'n'; } catch (...) { std::cerr EXCEPTION of unknown typen; } ‡ 6LQFH H[SUHVVLRQV IRU RSHUDWRU DUH JXDUDQWHHG WR HYDOXDWH IURP OHIW WR ULJKW 0LJKW RXWSXW EHIRUH elem: 7 elem: 14 elem: 21 elem: 28 EXCEPTION: :LOO RXWSXW VLQFH elem: 7 elem: 14 elem: 21 elem: 28 elem: EXCEPTION: ‹ E ,7FRPPXQLFDWLRQFRP noexcept 3DUW RI WKH )XQFWLRQ 7SH ‡ WSH VVWHP GLIIHUHQWLDWHV EHWZHHQ ± QRH[FHSW IXQFWLRQV ± IXQFWLRQV WKDW GRQ W JXDUDQWHH QRW WR WKURZ ‡ $ IXQFWLRQ WKDW PLJKW WKURZ FDQ W EH XVHG DV QRH[FHSW IXQFWLRQ ± 7KH RSSRVLWH LV ILQH void f1(); void f2() noexcept; GLIIHUHQW WSH WKDQ f1 void f3() noexcept(sizeof(int)4); VDPH WSH DV HLWKHU f1 RU f2 void f4() noexcept(sizeof(int)=4); GLIIHUHQW WSH WKDQ f3 Nico Josuttis C++17 @CodeHard 50
  • 168. ‹ E ,7FRPPXQLFDWLRQFRP noexcept 3DUW RI WKH )XQFWLRQ 7SH ‡ WSH VVWHP GLIIHUHQWLDWHV EHWZHHQ ± QRH[FHSW IXQFWLRQV ± IXQFWLRQV WKDW GRQ W JXDUDQWHH QRW WR WKURZ ‡ $ IXQFWLRQ WKDW PLJKW WKURZ FDQ W EH XVHG DV QRH[FHSW IXQFWLRQ WKH RSSRVLWH LV ILQH
  • 169. ‡ 7SH RI IXQFWLRQV ZLWK FRQGLWLRQDO QRH[FHSW VSHFLILFDWLRQV GHSHQGV RQ ZKDW WKH FRQGLWLRQ LHOGV ‡ 'QDPLF H[FHSWLRQ VSHFLILFDWLRQV ZHUH UHPRYHG void f1(); void f2() noexcept; GLIIHUHQW WSH WKDQ f1 void f3() noexcept(sizeof(int)4); VDPH WSH DV HLWKHU f1 RU f2 void f4() noexcept(sizeof(int)=4); GLIIHUHQW WSH WKDQ f3 VDPH WSH DV f2 LI f3 KDV VDPH WSH DV f1 void fnothrow() throw(); 2. EXW PD QRW XQZLQG VWDFN LI YLRODWHG VDPH WSH DV f2 void fthrow() throw(std::bad_alloc); (UURU LQYDOLG VLQFH ‹ E ,7FRPPXQLFDWLRQFRP noexcept 3DUW RI WKH )XQFWLRQ 7SH void f1(); void f2() noexcept; GLIIHUHQW WSH WKDQ I void (*fp)() noexcept; UHTXLUHV QRH[FHSW IXQFWLRQ fp = f2; 2. fp = f1; (UURU VLQFH void (*fp2)(); GRHVQ W UHTXLUH QRH[FHSW IXQFWLRQ fp2 = f2; 2. fp2 = f1; 2. FDQ DOVR XVH QRH[FHSW IXQFWLRQ
  • 170. templatetypename T void call(T op1, T op2); call(f1, f2); (UURU VLQFH I DQG I QRZ KDYH GLIIHUHQW WSHV
  • 171. templatetypename T1, typename T2 void call2(T1 op1, T2 op2); call2(f1, f2); 2. Nico Josuttis C++17 @CodeHard 51
  • 172. ‹ E ,7FRPPXQLFDWLRQFRP noexcept 3DUW RI WKH )XQFWLRQ 7SH SULPDU WHPSODWH LQ JHQHUDO WSH 7 LV QR IXQFWLRQ
  • 173. templatetypename T struct is_function : std::false_type { }; SDUWLDO VSHFLDOL]DWLRQV IRU DOO IXQFWLRQ WSHV templatetypename Ret, typename... Params struct is_functionRet (Params...) : std::true_type { }; templatetypename Ret, typename... Params struct is_functionRet (Params...) const : std::true_type { }; templatetypename Ret, typename... Params struct is_functionRet (Params...) : std::true_type { }; templatetypename Ret, typename... Params struct is_functionRet (Params...) const : std::true_type { }; SDUWLDO VSHFLDOL]DWLRQV IRU DOO IXQFWLRQ WSHV ZLWK QRH[FHSW templatetypename Ret, typename... Params struct is_functionRet (Params...) noexcept : std::true_type { }; templatetypename Ret, typename... Params struct is_functionRet (Params...) const noexcept : std::true_type { }; templatetypename Ret, typename... Params struct is_functionRet (Params...) noexcept : std::true_type { }; templatetypename Ret, typename... Params struct is_functionRet (Params...) const noexcept : std::true_type { }; QRZ LQVWHDG RI SDUWLDO VSHFLDOL]DWLRQV ‹ E ,7FRPPXQLFDWLRQFRP 5HOD[HG (QXPHUDWLRQ ,QLWLDOL]DWLRQ ‡ )RU HQXPHUDWLRQV ZLWK D IL[HG XQGHUOLQJ WSH RX FDQ XVH DQ LQWHJUDO YDOXH RI WKDW WSH IRU GLUHFW OLVW LQLWLDOL]DWLRQV ± DSSOLHV WR ERWK enum DQG enum class enum class Salutation { mr, mrs }; Salutation s4 = 0; (UURU DOO YHUVLRQV
  • 174. Salutation s5(0); (UURU DOO YHUVLRQV
  • 175. Salutation s6{0}; 2. VLQFH HUURU EHIRUH
  • 176. enum class Salut : char { mr, mrs }; Salut s7 = 0; (UURU DOO YHUVLRQV
  • 177. Salut s8(0); (UURU DOO YHUVLRQV
  • 178. Salut s9{0}; 2. VLQFH HUURU EHIRUH
  • 179. enum Flag { bit1=1, bit2=2, bit3=4 }; Flag f3{0}; VWLOO (UURU DOO YHUVLRQV
  • 180. enum Byte : unsigned char { }; Byte b1 = 42; (UURU DOO YHUVLRQV
  • 181. Byte b2(42); (UURU DOO YHUVLRQV
  • 182. Byte b3{42}; 2. VLQFH HUURU EHIRUH
  • 183. Byte b4 = {42}; (UURU DOO YHUVLRQV
  • 184. 7KLV LV ZK LW ZDV LQWURGXFHG ‡ ,QLWLDOL]DWLRQ RI QHZ LQWHJUDO WSHV DV HQXP ‡ 6HH std::byte Nico Josuttis C++17 @CodeHard 52
  • 185. ‹ E ,7FRPPXQLFDWLRQFRP ,QLWLDOL]DWLRQV ZLWK auto DQG {} ‡ auto a1(42); GLUHFW LQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQW auto a2{42}; GLUHFWOLVWLQLWLDOL]DWLRQ LQLWLDOL]HV VWGLQLWLDOL]HUBOLVWLQW! auto a3{1,2}; GLUHFWOLVWLQLWLDOL]DWLRQ LQLWLDOL]HV VWGLQLWLDOL]HUBOLVWLQW! auto a4 = 42; FRS LQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQW auto a5 = {42}; FRSOLVWLQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQLWLDOL]HUBOLVWLQW! auto a6 = {1,2}; FRSOLVWLQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQLWLDOL]HUBOLVWLQW! ‡ 6LQFH EXW VRPH FRPSLOHUV VXSSRUW LW EHIRUH
  • 186. auto x1(42); GLUHFW LQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQW auto x2{42}; GLUHFWOLVWLQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQW auto x3{1,2}; (UURU auto x4 = 42; FRS LQLWLDOL]DWLRQ LQLWLDOL]HV DQ LQW auto x5 = {42}; FRSOLVWLQLWLDOL]DWLRQ VWLOO LQLWLDOL]HV VWGLQLWLDOL]HUBOLVWLQW! auto x6 = {1,2}; FRSOLVWLQLWLDOL]DWLRQ VWLOO LQLWLDOL]HV VWGLQLWLDOL]HUBOLVWLQW! ‹ E ,7FRPPXQLFDWLRQFRP 1HZ /LEUDU RPSRQHQWV Nico Josuttis C++17 @CodeHard 53
  • 187. ‹ E ,7FRPPXQLFDWLRQFRP 1HZ %DVLF 'DWD 6WUXFWXUHV ‡ $IWHU SDLU! WXSOH! DGGV VRPH VPDUW GDWD WSHV WR KROG D YDOXH ± VWGRSWLRQDO! ‡ RSWLRQDOO KROGV D YDOXH ‡ HLWKHU HPSW RU KDV D YDOXH RI D VSHFLILF WSH ‡ DGDSWHG IURP ERRVWRSWLRQDO! ± VWGYDULDQW! ‡ KROGV D YDOXH WKDW PLJKW KDYH RQH RI PXOWLSOH SUHGHILQHG WSHV ‡ XVXDOO QHYHU HPSW RQO GXH WR VRPH H[FHSWLRQV
  • 188. ‡ GLIIHUV IURP ERRVWYDULDQW! ± VWGDQ! ‡ KROGV D YDOXH WKDW PLJKW KDYH DQ SRVVLEOH WSH ‡ PD EH HPSW ‡ DGDSWHG IURP ERRVWDQ! ‹ E ,7FRPPXQLFDWLRQFRP std::optional ‡ 6WUXFWXUH WR RSWLRQDOO KROG D YDOXH RI D FHUWDLQ WSH ± HLWKHU HPSW RU KDV D YDOXH ± QR QHHG WR GHDO ZLWK VSHFLDO YDOXHV VXFK DV 18// RU ‡ $GDSWHG IURP ERRVWRSWLRQDO ± std::nullopt LQVWHDG RI boost::none std::optionalstd::string noString; std::optionalstd::string optStr(hello); optStr = new value; *optStr = new value; if (optStr) { HTXLYDOHQW WR if (optStr.has_value()) std::string s = *optStr; XQGHILQHG EHKDYLRU LI QR YDOXH } try { std::string s = optStr.value(); H[FHSWLRQ LI QR YDOXH } catch (const std::bad_optional_access e) { optStr.reset(); PDNHV LW HPSW } Nico Josuttis C++17 @CodeHard 54
  • 189. ‹ E ,7FRPPXQLFDWLRQFRP ([DPSOH IRU std::optional #include optional #include string #include iostream std::optionalint asInt(const std::string s) UHWXUQV LQW RU QR LQW { try { return std::stoi(s); } catch (...) { return std::nullopt; } } int main() { for (auto s : {42, 077, hello, 0x33} ) { std::optionalint oi = asInt(s); if (oi) { std::cout convert ' s ' to int: *oi n; LQW } else { std::cout can't convert ' s ' to intn; QR LQW } } } 2XWSXW convert '42' to int: 42 convert ' 077' to int: 77 can't convert 'hello' to int convert '0x33' to int: 0 ‹ E ,7FRPPXQLFDWLRQFRP std::optional 2SHUDWLRQV PRYH VHPDQWLFV LV VXSSRUWHG std::optionalstd::string os; std::string s = hello; os = std::move(s); std::string s2 = *os; std::string s3 = std::move(*os); RPSDULVRQ ZRUN RQ WKH YDOXHV QR YDOXH DQ RWKHU YDOXH std::optionalbool ob0; if (ob false) WUXH std::optionalunsigned uo; if (uo 0) WUXH GLIIHUHQW WKDQ XVLQJ DV ERRO std::optionalbool ob{false}; if (!ob) IDOVH if (ob==false) WUXH std::optionalint* op{nullptr}; if (!op) IDOVH if (op==nullptr) WUXH Nico Josuttis C++17 @CodeHard 55
  • 190. ‹ E ,7FRPPXQLFDWLRQFRP std::optional RQVLGHUHG +DUPIXO ‡ %HZDUH RI DFFHVVLQJ WKH FRQWDLQHG REMHFW IRU WHPSRUDULHV ± /LIHWLPH LVVXHV ZLWK GLUHFW DFFHVV ± 'RQ W UHSODFH REMHFWV E RSWLRQDO REMHFWV EOLQGO std::optionalstd::string getString(); auto a = getString().value(); 2. FRS RI FRQWDLQHG REMHFW auto b = *getString(); (5525 XQGHILQHG EHKDYLRU LI std::nullopt const auto r1 = getString().value(); (5525 UHIHUHQFH WR GHOHWHG FRQWDLQHG REMHFW auto r2 = getString().value(); (5525 UHIHUHQFH WR GHOHWHG FRQWDLQHG REMHFW std::vectorint getVector(); for (int i : getVector()) { 2. std::cout i 'n'; } std::optionalstd::vectorint getOptVector(); for (int i : getOptVector().value()) { (5525 LWHUDWH RYHU GHOHWHG YHFWRU std::cout i 'n'; } ‹ E ,7FRPPXQLFDWLRQFRP 'HFODUDWLRQ RI VWGRSWLRQDO! template typename T class optional { public: using value_type = T; constexpr optional() noexcept; // observers: constexpr const T operator*() const; constexpr T operator*() ; constexpr T operator*() ; constexpr const T operator*() const; constexpr const T value() const; constexpr T value() ; constexpr T value() ; constexpr const T value() const; }; 6HH KWWSZJOLQNS IRU RXU SURSRVDO WR GHFODUH WKDW WKH UHWXUQ YDOXH GHSHQGV RQ WKH OLIHWLPH RI WKLV Nico Josuttis C++17 @CodeHard 56
  • 191. ‹ E ,7FRPPXQLFDWLRQFRP std::variant ‡ ORVH GLVFULPLQDWHG XQLRQ ± 6WUXFWXUH WR KROG D YDOXH RI RQH RI WKH VSHFLILHG alternatives ± 8QOLNH union ‡ 7KH WSH RI WKH FXUUHQW YDOXH LV DOZDV NQRZQ ‡ DQ KDYH DQ PHPEHU RI DQ WSH ‡ DQ EH EDVH FODVV ± 0XOWLSOH RFFXUUHQFHV RI VDPH WSH DUH VXSSRUWHG ‡ 6HPDQWLF XQLRQ HJ GLIIHUHQW VWULQJV IRU GLIIHUHQW GDWDEDVH FROXPQV
  • 192. ‡ ,QWHUIDFH ZLWK LQGH[ OLNH WXSOH ± 1R HPSW VWDWH ‡ DQ XVH std::monostate WR VLPXODWH LW ± 'HIDXOWRQVWUXFWLEOH LI ILUVW DOWHUQDWLYH LV GHIDXOW FRQVWUXFWLEOH ‡ DQ XVH std::monostate IRU LW ± 'LIIHUV IURP ERRVWYDULDQW ‡ 1R KHDS DOORFDWLRQ ‹ E ,7FRPPXQLFDWLRQFRP ([DPSOH IRU std::variant #include variant std::variantint, int, std::string var; VHWV ILUVW LQW WR LQGH[
  • 193. var = hello; VHWV VWULQJ LQGH[
  • 194. var.emplace1(42); VHWV VHFRQG LQW LQGH[
  • 195. try { auto s = std::getstd::string(var); WKURZV H[FHSWLRQ VHFRQG LQW FXUUHQWO VHW
  • 196. auto a = std::getdouble(var); FRPSLOHWLPH HUURU QR GRXEOH auto b = std::get3(var); FRPSLOHWLPH HUURU QR WK DOWHUQDWLYH auto c = std::getint(var); FRPSLOHWLPH HUURU LQW WZLFH auto i = std::get1(var); 2. L auto j = std::get0(var); WKURZV H[FHSWLRQ RWKHU LQW FXUUHQWO VHW
  • 197. std::get1(var) = 77; 2. EHFDXVH VHFRQG LQW DOUHDG VHW std::get0(var) = 99; WKURZV H[FHSWLRQ RWKHU LQW FXUUHQWO VHW
  • 198. } catch (const std::bad_variant_access e) { LI UXQWLPH HUURU std::cout Exception: e.what() 'n'; } Nico Josuttis C++17 @CodeHard 57
  • 199. ‹ E ,7FRPPXQLFDWLRQFRP std::variant 2SHUDWLRQV ‹ E ,7FRPPXQLFDWLRQFRP 7ULFN 8VDJH IRU std::variant #include variant H[SOLFLWO FKRRVH WKH DOWHUQDWLYH std::variantint, long var{std::in_place_index1, 11}; LQLWV ORQJ DOWKRXJK LQW SDVVHG LQGH[
  • 200. var = 22; VHWV LQW LQGH[
  • 201. var.emplace1(32); VHWV ORQJ DOWKRXJK LQW SDVVHG LQGH[
  • 202. LQLWLDOL]H YDULDQW ZLWK D VHW ZLWK ODPEGD DV VRUWLQJ FULWHULRQ auto sc = [] (int x, int y) { return std::abs(x) std::abs(y); }; std::variantstd::vectorint, std::setint,decltype(sc) v8{std::in_place_index1, {4, 8, -7, -2, 0, 5}, sc}; if (auto ip = std::get_if1(var); ip) { QRWH SDVV WKH DGGUHVV std::cout *ip: *ip 'n'; } QHZ if ZLWK LQLWLDOL]DWLRQ Nico Josuttis C++17 @CodeHard 58
  • 203. ‹ E ,7FRPPXQLFDWLRQFRP VWGYDULDQW! DQG VWGPRQRVWDWH struct NoDefConstr { NoDefConstr(int i) { } }; std::variantNoDefConstr, int v1; (5525 FDQ W GHIDXOW FRQVWUXFW ILUVW WSH std::variantstd::monostate, NoDefConstr v2; 2. YDOXH LV PRQRVWDWH^` std::cout index: v2.index() 'n'; SULQW FKHFN IRU PRQRVWDWH if (v2.index() == 0) { } if (!v2.index()) { } PRQRVWDWH PXVW EH ILUVW DOWHUQDWLYH if (std::holds_alternativestd::monostate(v2)) { } if (std::get_if0(v2)) { } if (std::get_ifstd::monostate(v2)) { } v2 = 42; v2 = std::monostate{}; PRQRVWDWH DJDLQ D ZD WR VLJQDO HPSWLQHVV D ZD WR VLJQDO HPSWLQHVV ‹ E ,7FRPPXQLFDWLRQFRP std::variant %HFRPLQJ (PSW ‡ variant PLJKW EHFRPH HPSW RQO E XQKDQGOHG H[FHSWLRQ ± 2QO LI XVLQJ WKH YDULDQW DIWHU H[FHSWLRQ ZLWKRXW UHLQLWLDOL]DWLRQ ‡ 7KHQ v.valueless_by_exception() == true v.index() == std::variant_npos struct S { operator int() { throw EXCEPTION; } DQ FRQYHUVLRQ WR LQW WKURZV }; std::variantfloat,int var{12.2}; try { var.emplace1(S()); RRSV WKURZV ZKLOH EHLQJ VHW } catch (...) { RRSV UHDOO GRQ W VHW YDU WR D QHZ GHILQHG VWDWH } var.valueless_by_exception() == true var.index() == std::variant_npos Nico Josuttis C++17 @CodeHard 59
  • 204. ‹ E ,7FRPPXQLFDWLRQFRP 'HULYLQJ IURP VWGYDULDQW! class Derived : public std::variantint, std::string { }; Derived d = {{hello}}; DJJUHJDWH LQLWLDOL]DWLRQ std::cout d.index() 'n'; SULQWV std::cout std::get1(d) 'n'; SULQWV KHOOR d.emplace0(77); std::cout std::get0(d) 'n'; SULQWV ‹ E ,7FRPPXQLFDWLRQFRP std::variant 9LVLWRUV std::variantint, std::string var(42); struct MyVisitor { void operator()(double d) const { std::cout d 'n'; } void operator()(int i) const { std::cout i 'n'; } void operator()(const std::string s) const { std::cout s 'n'; } }; std::visit(MyVisitor(), var); FRPSLOHWLPH HUURU LI QRW DOO SRVVLEOH WSHV VXSSRUWHG RU ZLWK DPELJXLWLHV std::visit([](const auto val) { FDOO ODPEGD IRU WKH DSSURSULDWH WSH std::cout val 'n'; }, var); ‡ 8VLQJ YLVLWRUV Nico Josuttis C++17 @CodeHard 60
  • 205. ‹ E ,7FRPPXQLFDWLRQFRP std::variant 9LVLWRUV struct MyVisitor { template typename T YLVLWRU IRU VLQJOH YDOXH RI DQ WSH void operator() (T var) { std::cout var; } void operator() (int i, double d, char c) { IRU VSHFLILF YDOXHV std::cout i ' ' d ' ' c; } void operator() (...) { IRU DOO RWKHU FDVHV std::cout no match; } }; std::variantint, std::string var1{12}; std::variantstd::string, double var2{13}; std::variantstd::string, char var3{'x'}; std::visit(MyVisitor(), var1, var2, var3); SULQWV [ var2 = hello; std::visit(MyVisitor(), var1, var2, var3); SULQWV QR PDWFK std::visit(MyVisitor(), var2); SULQWV KHOOR ‡ 0XOWL9LVLWRUV ‹ E ,7FRPPXQLFDWLRQFRP 5XQWLPH 3ROPRUSKLVP ([DPSOH ZLWK +HDS 0HPRU class GeoObj { public: virtual void move(Coord) = 0; virtual void draw() const = 0; virtual ~GeoObj() = default; }; class Circle : public GeoObj { private: Coord center; int rad; public: Circle (Coord c, int r); virtual void move(Coord c) override; virtual void draw() const override; }; class Line : public GeoObj { private: Coord from; Coord to; public: Line (Coord f, Coord t); virtual void move(Coord c) override; virtual void draw() const override; }; std::vectorGeoObj* createFig() { std::vectorGeoObj* f; Line* lp = new Line(Coord(1,2), Coord(3,4)); Circle* cp = new Circle(Coord(5,5), 2); f.push_back(lp); f.push_back(cp); return f; } void drawElems (const std::vectorGeoObj* v) { for (const auto geoobjptr : v) { geoobjptr-draw(); } } std::vectorGeoObj* fig = createFig(); drawElems(fig); for (const auto geoobjptr : fig) { geoobjptr-move(Coord(2,2)); } drawElems(fig); UHPRYH DOO HOHPHQWV LQ WKH YHFWRU for (auto geoobjptr : fig) { delete geoobjptr; geoobjptr = nullptr; NULL EHIRUH } fig.clear(); /LQH *HR2EM LUFOH Nico Josuttis C++17 @CodeHard 61
  • 206. ‹ E ,7FRPPXQLFDWLRQFRP 3ROPRUSKLVP ([DPSOH ZLWK std::variant class GeoObj { public: virtual void move(Coord) = 0; virtual void draw() const = 0; virtual ~GeoObj() = default; }; class Circle : public GeoObj { private: Coord center; int rad; public: Circle (Coord c, int r); virtual void move(Coord c) override; virtual void draw() const override; }; class Line : public GeoObj { private: Coord from; Coord to; public: Line (Coord f, Coord t); virtual void move(Coord c) override; virtual void draw() const override; }; using GeoObjVar = std::variantCircle, Line; std::vectorGeoObjVar createFig() { std::vectorGeoObjVar f; f.push_back(Line(Coord(1,2),Coord(3,4))); f.push_back(Circle(Coord(5,5),2)); return f; } void drawElems (const std::vectorGeoObjVar v) { for (const auto geoobj : v) { std::visit([] (const auto obj) { obj.draw(); }, geoobj); } } std::vectorGeoObjVar fig = createFig(); drawElems(fig); for (auto geoobj : fig) { std::visit([] (auto obj) { obj.move(Coord(2,2)); }, geoobj); } drawElems(fig); fig.clear(); UHPRYH DOO HOHPHQWV LQ WKH YHFWRU /LQH *HR2EM LUFOH ‡ QR SRLQWHUV ‡ QR QHZGHOHWH LQ DSSO FRGH ‡ REMHFWV ORFDWHG WRJHWKHU YLVLWRU XVHV D ORFDO YWDEOH ‹ E ,7FRPPXQLFDWLRQFRP 3ROPRUSKLVP ([DPSOH ZLWK std::variant class Circle { private: Coord center; int rad; public: Circle (Coord c, int r); void move(Coord c); void draw() const; }; class Line { private: Coord from; Coord to; public: Line (Coord f, Coord t); void move(Coord c); void draw() const; }; using GeoObjVar = std::variantCircle, Line; std::vectorGeoObjVar createFig() { std::vectorGeoObjVar f; f.push_back(Line(Coord(1,2),Coord(3,4))); f.push_back(Circle(Coord(5,5),2)); return f; } void drawElems (const std::vectorGeoObjVar v) { for (const auto geoobj : v) { std::visit([] (const auto obj) { obj.draw(); }, geoobj); } } std::vectorGeoObjVar fig = createFig(); drawElems(fig); for (auto geoobj : fig) { std::visit([] (auto obj) { obj.move(Coord(2,2)); }, geoobj); } drawElems(fig); fig.clear(); UHPRYH DOO HOHPHQWV LQ WKH YHFWRU ‡ QR FRPPRQ EDVH FODVV ‡ QR YLUWXDO IXQFWLRQV /LQH *HR2EM LUFOH YLVLWRU XVHV D ORFDO YWDEOH ‡ QR SRLQWHUV ‡ QR QHZGHOHWH LQ DSSO FRGH ‡ REMHFWV ORFDWHG WRJHWKHU Nico Josuttis C++17 @CodeHard 62
  • 207. ‹ E ,7FRPPXQLFDWLRQFRP std:any ‡ 7SH WR KROG DQ SRVVLEOH YDOXH RI DQ WSH ± PD EH HPSW ‡ $GDSWHG IURP ERRVWDQ std::any empty; std::any anyVal(42); anyVal = std::string(hello); anyVal = oops; %HZDUH WSH LV FRQVW FKDU VR VWRUHV WKH DGGUHVV if (anyVal.has_value()) { if (anyVal) QRW VXSSRUWHG if (anyVal.type() == typeid(std::string)) { type()==typeid(void) LI HPSW std::string s = std::any_caststd::string(anyVal); } } try { int i = std::any_castint(anyVal); WSH PXVW PDWFK H[DFWO RQO FRQVWUHIV LJQRUHG
  • 208. } catch (std::bad_any_cast) { anyVal.reset(); PDNHV LW HPSW } ‹ E ,7FRPPXQLFDWLRQFRP std::any 2SHUDWLRQV Nico Josuttis C++17 @CodeHard 63
  • 209. ‹ E ,7FRPPXQLFDWLRQFRP 0RYH 6HPDQWLFV ZLWK std:any ‡ 7SHV LQ VWGDQ PXVW EH FRSDEOH ± 0RYHRQO WSHV DUH QRW VXSSRUWHG ‡ %XW RX FDQ XVH PRYH VHPDQWLFV std::string s(a pretty long string value (disabling SSO)); std::cout s: s 'n'; RXWSXWV WKH LQLWLDOL]HG VWULQJ std::any a; a = std::move(s); PRYH V LQWR D std::cout s: s 'n'; SUREDEO RXWSXWV DQ HPSW VWULQJ s = std::any_caststd::string(std::move(a)); PRYH VWULQJ LQ D LQWR V std::cout s: s 'n'; RXWSXWV WKH RULJLQDO VWULQJ ‹ E ,7FRPPXQLFDWLRQFRP std::byte ‡ 7SH UHSUHVHQWLQJ D EWH ± 1RW DQ LQWHJHU QRW D FKDUDFWHU ± 2SHUDWRUV = = = | |= = ^ ^= ~ == != = = sizeof ‡ 3OXV to_integerintegraltype(byte) std::byte b1{0xFF}; 2. DV IRU DOO HQXPV ZLWK IL[HG XQGHUOLQJ WSH VLQFH
  • 210. std::byte b2{0b1111'0000}; std::byte[4] b4{0xFF, 0, 0, 0}; if (b1 == b4[0]) { b1 = 4; } std::byte b0; XQGHILQHG YDOXH std::byte bx(42); (UURU std::byte by = 42; (UURU if (b1) (UURU if (b1 != std::byte{0}) 2. if (to_integerbool(b2)) (UURU $'/ GRHVQ W ZRUN KHUH
  • 211. if (std::to_integerbool(b2)) 2. std::cout sizeof(b0); DOZDV Nico Josuttis C++17 @CodeHard 64
  • 212. ‹ E ,7FRPPXQLFDWLRQFRP VWGEWH 'HILQLWLRQ LQ WKH 6WDQGDUG namespace std { enum class byte : unsigned char {}; EWH WSH RSHUDWLRQV template typename IntType constexpr byte operator (byte b, IntType shift) noexcept; template typename IntType constexpr byte operator= (byte b, IntType shift) noexcept; template typename IntType constexpr byte operator (byte b, IntType shift) noexcept; template typename IntType constexpr byte operator= (byte b, IntType shift) noexcept; constexpr byte operator|= (byte l, byte r) noexcept; constexpr byte operator| (byte l, byte r) noexcept; constexpr byte operator= (byte l, byte r) noexcept; constexpr byte operator (byte l, byte r) noexcept; constexpr byte operator^= (byte l, byte r) noexcept; constexpr byte operator^ (byte l, byte r) noexcept; constexpr byte operator~ (byte b) noexcept; template typename IntType constexpr IntType to_integer (byte b) noexcept; } ‹ E ,7FRPPXQLFDWLRQFRP std::string_view ‡ +DQGOH IRU UHDGRQO FKDUDFWHU VHTXHQFH ± /LIHWLPH RI WKH GDWD QRW FRQWUROOHG EH WKH REMHFW ± 1R DOORFDWRU VXSSRUW ± 3DVVLQJ E YDOXH LV FKHDS ‡ 'LIIHUV IURP VWULQJV DV IROORZV ± 1RW JXDUDQWHHG WR EH QXOO WHUPLQDWHG QR 17%6
  • 213. ‡ RX FDQ SODFH D ? DV ODVW FKDUDFWHU WKRXJK ± 9DOXH LV nullptr DIWHU GHIDXOW FRQVWUXFWLRQ ‡ 7KHQ data()==nullptr size()==0 VWULQJ G D D ?W VWULQJBYLHZ G D DWV R HP H P RL PQ U OHQ GDWD OHQ GDWD ‡ $OZDV XVH size() EHIRUH XVLQJ WKH GDWD operator[]data()
  • 215. ‹ E ,7FRPPXQLFDWLRQFRP std::string_view ‡ +HDGHU string_view ‡ +DV VRPH WSLFDO VWULQJ VXSSRUW ± $OVR u16string_view u32string_view wstring_view ± RUUHVSRQGLQJ OLWHUDO RSHUDWRU LV GHILQHG ‡ 6XIIL[ sv ± std::quoted() LV VXSSRUWHG ± +DVK YDOXHV PDWFK ZLWK KDVK YDOXHV RI std::string ‡ 6WLOO RSHQ LQWHJUDWLRQV ± 1R UHJH[ VXSSRUW #include chrono using namespace std::literals; auto s = R(somevalue)sv; std::cout quoted(s); RXWSXW somevalue s Y D XOV R H ??P H ? OHQ GDWD ‹ E ,7FRPPXQLFDWLRQFRP std::string_view 2SHUDWLRQV XQOLNH VWGVWULQJ Nico Josuttis C++17 @CodeHard 66
  • 216. ‹ E ,7FRPPXQLFDWLRQFRP std::string_view ‡ RQYHUVLRQ VWULQJ ! VWULQJBYLHZ LV FKHDS ! ,PSOLFLW FRQYHUVLRQ ‡ RQYHUVLRQ VWULQJBYLHZ ! VWULQJ LV H[SHQVLYH ! ([SOLFLW FRQYHUVLRQ void foo_s (const string s); void foo_v (string_view sv); foo_s(some value); FRPSXWHV OHQJWK DOORFDWHV PHPRU FRSLHV FKDUDFWHUV foo_v(some value); FRPSXWHV OHQJWK RQO VWULQJ VWULQJBYLHZ Y D XOV R HP H ? OHQ GDWD OHQ GDWD Y D XOV R HP H ? ‹ E ,7FRPPXQLFDWLRQFRP RQYHUWLQJ $3, V IURP string WR string_view #include string templatetypename Coll void printElems(const Coll coll, const std::string prefix) { SULQW HDFK HOHPHQW ZLWK D OHDGLQJ SUHIL[ for (const auto elem : coll) { std::cout prefix elem 'n'; } } #include string_view templatetypename Coll void printElems(const Coll coll, std::string_view prefix) { SULQW HDFK HOHPHQW ZLWK D OHDGLQJ SUHIL[ for (const auto elem : coll) { std::cout prefix elem 'n'; } } VDYHV QHZPDOORF IRU printElems(myVector, - Coll Element: ); VWLOO ZRUNV DV EHIRUH IRU std::string getPrefix(); ... printElems(myVector, getPrefix()); %HZDUH 2QO 2. EHFDXVH ‡ QR QXOO WHUPLQDWRU UHTXLUHG ‡ data() QRW XVHG nullptr
  • 217. ‡ OLIHWLPH 2. Nico Josuttis C++17 @CodeHard 67
  • 218. ‹ E ,7FRPPXQLFDWLRQFRP RQYHUWLQJ $3, V IURP string WR string_view #include string templatetypename Coll void printElems(const Coll coll, const std::string prefix) { SULQW HDFK HOHPHQW ZLWK D OHDGLQJ SUHIL[ for (const auto elem : coll) { std::cout prefix elem 'n'; } } #include string_view templatetypename Coll void printElems(const Coll coll, std::string_view prefix) { SULQW HDFK HOHPHQW ZLWK D OHDGLQJ SUHIL[ for (const auto elem : coll) { std::cout prefix elem 'n'; } } ZLWK ERWK SURYLGHG printElems(myVector, - Coll Element: ); (UURU DPELJXRXV ‹ E ,7FRPPXQLFDWLRQFRP RQYHUWLQJ $3, V IURP string WR string_view #include string class Customer { std::string name; public: Customer (const std::string n) : name(n) { } }; #include string #include string_view class Customer { std::string name; public: Customer (std::string_view n) : name(n) { } }; VDYHV QHZPDOORF IRU Customer c1(Enterprise Applications); EXW DGGV QHZPDOORF IRU std::string getName(); ... Customer c2(getName()); 'RQ W XVH std::string_view LQ FDOO VHTXHQFHV IRU std::string Nico Josuttis C++17 @CodeHard 68
  • 219. ‹ E ,7FRPPXQLFDWLRQFRP RQVWUXFWRUV VKRXOG PRYH LQLWLDOL]H PHPEHUV IURP EYDOXH SDUDPHWHUV ,QLWLDOL]LQJ 'DWD 0HPEHUV VLQFH #include string class Customer { std::string name; public: Customer (const std::string n) : name(n) { } }; #include string #include string_view class Customer { std::string name; public: Customer (std::string n) : name(std::move(n)) { } }; 9 VDYHV QHZPDOORF IRU Customer c1(Enterprise Applications); DQG VDYHV DQ QHZPDOORF IRU std::string getName(); ... Customer c2(getName()); ‹ E ,7FRPPXQLFDWLRQFRP VWULQJBYLHZ RQVLGHUHG +DUPIXO ‡ 1(9(5 XVH VWGVWULQJBYLHZ DV UHWXUQ WSH ± 6WULQJ YLHZV DUH DV EDG DV SRLQWHUV ZRUVH WKDQ UHIHUHQFHV
  • 220. std::string_view concat (std::string_view sv1, std::string_view sv2) { return std::string(sv1) + std::string(sv2); )DWDO 5XQWLPH (5525 } UHWXUQ YDOXH UHIHUV WR PHPRU RI GHVWUXFWHG VWULQJ std::string str = hello; std::cout concat(str, world) 'n'; IDWDO EXW FRPSLOHV std::string s1 = concat(str, world); IDWDO EXW FRPSLOHV auto s2 = concat(str, world); IDWDO EXW FRPSLOHV auto s3 = concat(str, world); IDWDO EXW FRPSLOHV std::string_view sv = concat(str, world); IDWDO EXW FRPSLOHV ‡ 1RW HYHQ FRPSLOHU ZDUQLQJV HW