32
Nico Josuttis C++17 @MeetingCpp 11/2019 1

Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template void

  • Upload
    others

  • View
    11

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ �� ����

�������� �������������������

����� �������

�����

�������������������

���� !���"��

���������� ������ ������ �� ����

���#����"��

��������

��$�"����

���%&�������

����

Nico Josuttis C++17

@MeetingCpp 11/2019 1

Page 2: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

'������(����int i1 = 0; ���"���int i2(0); ������)int i3{0}; �������

���������� ������ ������ ��� ���

*"���"+����"�,�"���'������(����int i1 = 0; ���"���int i2(0); ������)int i3{0}; �������int i0{}; ������������$���"�������������()�AnyTypet0{}; ��-.����������(����-������ ��!� ������0"nullptr���

unsigned long l1{4.8}; ���//0/1���$234-�""�5���-$������$unsigned long l2{i1}; ���//0/1���$234-�""�5���-$������$

std::vector<int> v1{8, 15};�������������"61����7�vector<int> v1(8,15)3

class C { int v{42};���}; ������������8�"���9����������5�$9�"�enumclassMyIntegralEnum;MyIntegralEnume{17}; ��0:��������� 1����9�"�������������;��"��$3struct Base {

double value;};struct Data : Base {

std::string name;};

Data s{{6.7}, "book"}; ����"�����������(�������������!��� ������� ��#$$�%�Data s0{}; ������4{{0.0}, ""}

&*"���"�����"�$�"����������(����'5��9{(}<���5��9���=

Nico Josuttis C++17

@MeetingCpp 11/2019 2

Page 3: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

���������4if<if<#"���<�$=�"$�

����

���������� ������ ������ ��� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){

coll.push_back(x);}

template <typename Coll>voidinsertAsString(intx, Coll& coll){coll.push_back(std::to_string(x));�����.�"�����"����$����"�

}

template <typename Coll>voidinsertAsString(doublex, Coll& coll){coll.push_back(std::to_string(x));�����.�"�����"����$����"�

}

std::vector<std::string> values;

insertAsString("hello", values); ��0:insertAsString(42, values); �����$��.�"��$insertAsString(0.7, values); �����$��.�"��$

�����"���9��"double

Nico Josuttis C++17

@MeetingCpp 11/2019 3

Page 4: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){

if (std::is_arithmetic<T>::value) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}}

std::vector<std::string> values;

insertAsString("hello", values); ���������;�����//0/insertAsString(42, values); ���������;�����//0/insertAsString(0.7, values); ���������;�����//0/

���������� ������ ������ �� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){

if (std::is_arithmetic<T>::value) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}}

std::vector<std::string> values;

insertAsString("hello", values); ���������;�����//0/

iflock.cpp: In instantiation of 'void insertAsString(T, Coll&) [with T = const char*; Coll = std::vector<std::__cxx1iflock.cpp:97:34: required from hereiflock.cpp:46:34:error: no matching function for call to 'to_string(const char*&)'

coll.push_back(std::to_string(x));~~~~~~~~~~~~~~^~~

In file included from /cygdrive/p/gcc/gcc82-include/string:52,from /cygdrive/p/gcc/gcc82-include/bits/locale_classes.h:40,from /cygdrive/p/gcc/gcc82-include/bits/ios_base.h:41,from /cygdrive/p/gcc/gcc82-include/ios:42,from /cygdrive/p/gcc/gcc82-include/ostream:38,from /cygdrive/p/gcc/gcc82-include/iostream:39,from iflock.cpp:1:

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6446:3: note: candidate: 'std::__cxx11::string std::__cxx11::to_stto_string(int __val)^~~~~~~~~

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6446:3: note: conversion of argument 1 would be ill-formed:iflock.cpp:46:35:error: invalid conversion from 'const char*' to 'int' [-fpermissive]

coll.push_back(std::to_string(x));^

In file included from /cygdrive/p/gcc/gcc82-include/string:52,from /cygdrive/p/gcc/gcc82-include/bits/locale_classes.h:40,from /cygdrive/p/gcc/gcc82-include/bits/ios_base.h:41,from /cygdrive/p/gcc/gcc82-include/ios:42,from /cygdrive/p/gcc/gcc82-include/ostream:38,from /cygdrive/p/gcc/gcc82-include/iostream:39,from iflock.cpp:1:

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6451:3: note: candidate: 'std::__cxx11::string std::__cxx11::to_stto_string(unsigned __val)^~~~~~~~~

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6451:3: note: conversion of argument 1 would be ill-formed:iflock.cpp:46:35:error: invalid conversion from 'const char*' to 'unsigned int' [-fpermissive]

coll.push_back(std::to_string(x));^

In file included from /cygdrive/p/gcc/gcc82-include/string:52,from /cygdrive/p/gcc/gcc82-include/bits/locale_classes.h:40,from /cygdrive/p/gcc/gcc82-include/bits/ios_base.h:41,from /cygdrive/p/gcc/gcc82-include/ios:42,from /cygdrive/p/gcc/gcc82-include/ostream:38,from /cygdrive/p/gcc/gcc82-include/iostream:39,from iflock.cpp:1:

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6457:3: note: candidate: 'std::__cxx11::string std::__cxx11::to_stto_string(long __val)^~~~~~~~~

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6457:3: note: conversion of argument 1 would be ill-formed:iflock.cpp:46:35:error: invalid conversion from 'const char*' to 'long int' [-fpermissive]

coll.push_back(std::to_string(x));^

In file included from /cygdrive/p/gcc/gcc82-include/string:52,from /cygdrive/p/gcc/gcc82-include/bits/locale_classes.h:40,from /cygdrive/p/gcc/gcc82-include/bits/ios_base.h:41,from /cygdrive/p/gcc/gcc82-include/ios:42,from /cygdrive/p/gcc/gcc82-include/ostream:38,from /cygdrive/p/gcc/gcc82-include/iostream:39,from iflock.cpp:1:

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6462:3: note: candidate: 'std::__cxx11::string std::__cxx11::to_stto_string(unsigned long __val)^~~~~~~~~

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6462:3: note: conversion of argument 1 would be ill-formed:iflock.cpp:46:35:error: invalid conversion from 'const char*' to 'long unsigned int' [-fpermissive]

coll.push_back(std::to_string(x));^

In file included from /cygdrive/p/gcc/gcc82-include/string:52,from /cygdrive/p/gcc/gcc82-include/bits/locale_classes.h:40,from /cygdrive/p/gcc/gcc82-include/bits/ios_base.h:41,from /cygdrive/p/gcc/gcc82-include/ios:42,from /cygdrive/p/gcc/gcc82-include/ostream:38,from /cygdrive/p/gcc/gcc82-include/iostream:39,from iflock.cpp:1:

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6468:3: note: candidate: 'std::__cxx11::string std::__cxx11::to_stto_string(long long__val)^~~~~~~~~

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6468:3: note: conversion of argument 1 would be ill-formed:iflock.cpp:46:35:error: invalid conversion from 'const char*' to 'long longint' [-fpermissive]

coll.push_back(std::to_string(x));^

In file included from /cygdrive/p/gcc/gcc82-include/string:52,from /cygdrive/p/gcc/gcc82-include/bits/locale_classes.h:40,from /cygdrive/p/gcc/gcc82-include/bits/ios_base.h:41,from /cygdrive/p/gcc/gcc82-include/ios:42,from /cygdrive/p/gcc/gcc82-include/ostream:38,from /cygdrive/p/gcc/gcc82-include/iostream:39,from iflock.cpp:1:

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6474:3: note: candidate: 'std::__cxx11::string std::__cxx11::to_stto_string(unsigned long long__val)^~~~~~~~~

/cygdrive/p/gcc/gcc82-include/bits/basic_string.h:6474:3: note: conversion of argument 1 would be ill-formed:iflock.cpp:46:35:error: invalid conversion from 'const char*' to 'long longunsigned int' [-fpermissive]

Nico Josuttis C++17

@MeetingCpp 11/2019 4

Page 5: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){if constexpr(std::is_arithmetic<T>::value) { ��0:���������

coll.push_back(std::to_string(x));}else {coll.push_back(x);

}}

std::vector<std::string> values;

insertAsString("hello", values); ��0:insertAsString(42, values); ��0:insertAsString(0.7, values); ��0:

���������� ������ ������ ���� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){if constexpr(std::is_arithmetic_v<T>) { ��0:���������

coll.push_back(std::to_string(x));}else {coll.push_back(x);

}}

std::vector<std::string> values;

insertAsString("hello", values); ��0:insertAsString(42, values); ��0:insertAsString(0.7, values); ��0:

Nico Josuttis C++17

@MeetingCpp 11/2019 5

Page 6: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){if constexpr(std::is_arithmetic_v<T>) { ��"��9������6��?

coll.push_back(std::to_string(x));}elseif constexpr(!std::is_same_v<T,std::nullptr_t>) { �����������"?

coll.push_back(x);}else {static_assert(false, "invalid argtype for insertAsString()");

}}

std::vector<std::string> values;

insertAsString("hello", values); ���//0/insertAsString(42, values); ���//0/insertAsString(0.7, values); ���//0/insertAsString(nullptr, values); ���//0/

�""�"4'�.��$�������$���������')!���������������������������'*� ����������+,�����������������

��,������������, ����,��������'-� ��������-���� �#$$��� �������

���������� ������ ������ ���� ���

=���"��!���������'���"�>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){if constexpr(std::is_arithmetic_v<T>) { ��"��9������6��?

coll.push_back(std::to_string(x));}elseif constexpr(!std::is_same_v<T,std::nullptr_t>) { �����������"?

coll.push_back(x);}else {static_assert(sizeof(T) == 0, "invalid argtype for insertAsString()");

}}

std::vector<std::string> values;

insertAsString("hello", values); ��0:insertAsString(42, values); ��0:insertAsString(0.7, values); ��0:insertAsString(nullptr, values); ���//0/

Nico Josuttis C++17

@MeetingCpp 11/2019 6

Page 7: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

+����@��7=�"$59���'���"����>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){

if constexpr(std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}}

std::vector<std::string> values;std::mutex valuesMx;

{std::lock_guard<std::mutex>lg{valuesMx};insertAsString("hello", values);��0:insertAsString(42, values); ��0:insertAsString(0.7, values); ��0:

}

59���.����"���7�$

���������� ������ ������ ���� ���

+����@��7=�"$59���'���"����>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){

if constexpr(std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}}

std::vector<std::string> values;std::mutex valuesMx;

{std::lock_guardlg{valuesMx}; ��0:<$�$����std::lock_guard<std::mutex>insertAsString("hello", values);��0:insertAsString(42, values); ��0:insertAsString(0.7, value ��0:

}

�#A,4����#������A"������,�$������

Nico Josuttis C++17

@MeetingCpp 11/2019 7

Page 8: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

+����@��7=�"$59���'���"����>�"����������

template <typename T, typename Coll>voidinsertAsString(T x, Coll& coll){

�������9�"�����<59�"������9���$�B������7�$if constexpr(std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}�������9�"�����<59�"������9���$�B������7�$

}

std::vector<std::string> values;std::mutex valuesMx;

{std::lock_guardlg{valuesMx};insertAsString("hello", values);��0:insertAsString(42, values); ��0:insertAsString(0.7, values); ��0:

}

���������� ������ ������ ���� ���

=���"��!���������'���"�>�"����������5��9�����

template <typename T, typename Coll, typename Mx>voidinsertAsString(T x, Coll& coll, Mx& mutex){

�������9�"�����<59�"������9���$�B������7�${std::lock_guardlg{mutex};if constexpr(std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}}�������9�"�����<59�"������9���$�B������7�$

}

std::vector<std::string> values;std::mutex valuesMx;

insertAsString("hello", values, valuesMx);��0:insertAsString(42, values, valuesMx); ��0:insertAsString(0.7, values, valuesMx); ��0:

Nico Josuttis C++17

@MeetingCpp 11/2019 8

Page 9: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

=���"��!���������'���"�>�"����������5��9�����

template <typename T, typename Coll, typename Mx>voidinsertAsString(T x, Coll& coll, Mx& mutex){

�������9�"�����<59�"������9���$�B������7�$if constexpr(std::lock_guardlg{mutex};std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}�������9�"�����<59�"������9���$�B������7�$

}

std::vector<std::string> values;std::mutex valuesMx;

insertAsString("hello", values, valuesMx);��0:insertAsString(42, values, valuesMx); ��0:insertAsString(0.7, values, valuesMx); ��0:

����if����������� �.�����

���������� ������ ������ ��� ���

=���"��!���������'���"�>�"����������5��9�����

template <typename T, typename Coll, typename...Mxs>voidinsertAsString(T x, Coll& coll, Mxs&...mutexes){

�������9�"�����<59�"������9���$�B������7�$if constexpr(std::scoped_locklg{mutexes...};std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}�������9�"�����<59�"������9���$�B������7�$

}

std::vector<std::string> values;std::mutex valuesMx;std::shared_mutexreadonlyMx;

insertAsString("hello", values, valuesMx); ��0:<����$��������7�$insertAsString(42, values, valuesMx, readonlyMx); ��0:<���9����������7�$insertAsString(0.7, values); ��0:<����������7�$

+����9�$�$���7.��$������"��9��������std::lock()

Nico Josuttis C++17

@MeetingCpp 11/2019 9

Page 10: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

=���"��!���������'���"�>�"����������5��9�����

template <typename T, typename Coll, typename... Mxs>voidinsertAsString(T x, Coll& coll, Mxs&... mutexes){

�������9�"�����<59�"������9���$�B������7�$if constexpr(std::scoped_lock{mutexes...};std::is_arithmetic_v<T>) {coll.push_back(std::to_string(x));

}else {coll.push_back(x);

}�������9�"�����<59�"������9���$�B������7�$

}

std::vector<std::string> values;std::mutex valuesMx;std::shared_mutexreadonlyMx;

insertAsString("hello", values, valuesMx); ��???insertAsString(42, values, valuesMx, readonlyMx); ��???insertAsString(0.7, values); ��???

!��"�������""�"4��������������"���7�$���"�������(����

00*><����$�����������7�$00*><���9�������������7�$�������1���3���7�$

���������� ������ ������ ���� ���

��6��5!���"���$>�����5#"��

template <typename T, typename Coll, typename... Mxs>void insertAsString(T x, Coll& coll, Mxs&... mutexes){

�������9�"�����<59�"������9���$�B������7�$if constexpr(std::scoped_locklg{mutexes...};std::is_arithmetic_v<T>)

'C��5����"��4&#��,� �������if&if����������� �.�����&std::scoped_lock<>

&#�/0�� �������, ������1���������� �����&�,��������������_v�����+

'�#"�4&0��2���3�,����������������� � 3�1����

Nico Josuttis C++17

@MeetingCpp 11/2019 10

Page 11: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4�#A,��"std::vector<>namespace std {template <class T, class Allocator = allocator<T>>classvector{public:vector()noexcept(noexcept(Allocator()));explicitvector(const Allocator&) noexcept;explicitvector(size_tn, const Allocator& = Allocator());vector(size_t n, const T& value, const Allocator& = Allocator());template <class InputIterator>vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

vector(const vector& x);vector(vector&&)noexcept;vector(const vector&, const Allocator&);vector(vector&&, const Allocator&);vector(initializer_list<T>, const Allocator& = Allocator());���

};}

std::vector v1{8, 15}; ��vector<int>5��9%��������std::vector v2{8}; ��vector<int>5��9��������

��vector<int>5��9%����������vector<int>5��9��������

���������� ������ ������ ���� ���

���� 4�#A,��"std::vector<>namespace std {template <class T, class Allocator = allocator<T>>classvector{public:vector()noexcept(noexcept(Allocator()));explicitvector(const Allocator&) noexcept;explicitvector(size_tn, const Allocator& = Allocator());vector(size_tn, const T& value, const Allocator& = Allocator());template <class InputIterator>vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

vector(const vector& x);vector(vector&&)noexcept;vector(const vector&, const Allocator&);vector(vector&&, const Allocator&);vector(initializer_list<T>, const Allocator& = Allocator());���

};}

std::vector v1{8, 15}; ��vector<int>5��9%��������std::vector v2{8}; ��vector<int>5��9��������std::vector v3(8, 15); ��vector<int>5��9)����������.����Cstd::vector v4(8); ���//0/4��B�$�$�����������6��std::vector v5(8, ""); ���//0/4vector<char[1]>

*� ����� ������ ������3���T��������� �4T����������� �

��vector<int>5��9%����������vector<int>5��9����������vector<int>5��9)����������.����C���//0/4��B�$�$�����������6����vector<char[1]>$�$���$<������9T����//0/

Nico Josuttis C++17

@MeetingCpp 11/2019 11

Page 12: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4�#A,��"std::vector<>namespace std {template <class T, class Allocator = allocator<T>>classvector{public:vector()noexcept(noexcept(Allocator()));explicitvector(const Allocator&) noexcept;explicitvector(size_tn, const Allocator& = Allocator());vector(size_tn, const T& value, const Allocator& = Allocator());template <class InputIterator>vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

vector(const vector& x);vector(vector&&)noexcept;vector(const vector&, const Allocator&);vector(vector&&, const Allocator&);vector(initializer_list<T>, const Allocator& = Allocator());���

};}

std::set<std::string> coll;

std::vector v6{coll.begin(), coll.end()};std::vector v7(coll.begin(), coll.end()); ���//0/4��B�$�$�����������6��

�"���������(�����7����������DE.����"�����"��"�

��$�$����vector<set<string>>::iterator>���//0/4��B�$�$�����������6��

v7

v6

���������� ������ ������ ���� ���

���� 4�#A,��"std::vector<>5��9,�$������=��$��namespace std {template <class T, class Allocator = allocator<T>>classvector{public:vector()noexcept(noexcept(Allocator()));explicitvector(const Allocator&) noexcept;explicitvector(size_tn, const Allocator& = Allocator());vector(size_tn, const T& value, const Allocator& = Allocator());template <class InputIterator>vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

vector(const vector& x);vector(vector&&)noexcept;vector(const vector&, const Allocator&);vector(vector&&, const Allocator&);vector(initializer_list<T>, const Allocator& = Allocator());���

};

template<typename Iter>vector(Iter, Iter) ->vector<typename iterator_traits<Iter>::value_type>;

}

std::set<std::string> coll;std::vector v6{coll.begin(), coll.end()};������4$�$����vector<set<string>>::iterator>std::vector v7(coll.begin(), coll.end()); ��0:4$�$����vector<std::string>

,�$���������$�����������$

��$�$����vector<set<string>>::iterator>��0:4$�$����vector<std::string>

v7

v6

Nico Josuttis C++17

@MeetingCpp 11/2019 12

Page 13: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4��$44.����"FE�#A,��">�"���@���"��namespace std {template <class T, class Allocator = allocator<T>>classvector{public:vector()noexcept(noexcept(Allocator()));explicitvector(const Allocator&) noexcept;explicitvector(size_tn, const Allocator& = Allocator());vector(size_tn, const T& value, const Allocator& = Allocator());template <class InputIterator>vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

vector(const vector& x);vector(vector&&)noexcept;vector(const vector&, const Allocator&);vector(vector&&, const Allocator&);vector(initializer_list<T>, const Allocator& = Allocator());���

};

template<class Iter,class Allocator = allocator<typename iterator_traits<Iter>::value_type>>

vector(Iter, Iter, Allocator = Allocator())->vector<typename iterator_traits<Iter>::value_type, Allocator>;

}

std::vector v8{"hi", "world"}; ��???std::vector v9("hi", "world"); ��???

,�$���������$���� ��,� �����

��vector<const char> 5��9distance-"hi"-"world"����������vector<const char*> 5��9%��������

��"�$��������

v9

v8

,��B�����#A,������$�$����������.����

���������� ������ ������ ���� ���

������%��4!��$<�.������<

auto<>�"���@���"��

����

Nico Josuttis C++17

@MeetingCpp 11/2019 13

Page 14: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

G"�$��#�������

voidprint(){}

template <typename T, typename...Types>voidprint(TfirstArg, Types...args ){

std::cout <<firstArg<<'\n';

print( args...);

}

std::string str = "world";print ( "hello", 7.5, str )

=> print<const char*,���> ( "hello",7.5, str )std::cout <<"hello"<<'\n';print ( 7.5, str )

=> print<double,���> ( 7.5, str )std::cout << 7.5<< '\n';print ( str )

=> print<std::string> ( str)std::cout << str<< '\n';print ( )

���������� ������ ������ ��� ���

G"�$��#�������

voidprint(){}

template <typename T, typename...Types>voidprint(TfirstArg, Types...args ){

std::cout <<firstArg<<'\n';

print( args...);

}

std::string str = "world";print ( "hello", 7.5, str )

=> print<const char*,���> ( "hello", 7.5, str )std::cout <<"hello"<<'\n';print ( 7.5, str )

=> print<double,���> ( 7.5, str )std::cout << 7.5<< '\n';print ( str )

=> print<std::string> ( str)std::cout << str<< '\n';print ( )

��$��������.��6�������$4

std::string str = "world";std::cout <<"hello" <<'\n';std::cout << 7.5 << '\n';std::cout << str << '\n';

Nico Josuttis C++17

@MeetingCpp 11/2019 14

Page 15: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

���� 4�������;#���if�$G"�$��#�������

template <typename T, typename...Types>voidprint(T firstArg, Types...args){std::cout << firstArg<< '\n';if (sizeof...(args) > 0) {

print(args...);}

}

template <typename T, typename... Types>voidprint(T firstArg, Types...args){std::cout << firstArg<< '\n';ifconstexpr(sizeof...(args) > 0) { �����������

print(args...);��0:4������������$��sizeof...(args)==0}

}

���""�"4���$��"���13��sizeof...(args)==0

���������� ������ ������ ���� ���

���� 4!��$���"�������

'A���6���"6���"��"����������������"����"��7template <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) ��%�foldSum1(i, 1000, i) ���&�%foldSum1(std::string{"hi"}, "hi", "hi") ��0:49�9�9�foldSum1() ���//0/

i = foldSum2(17, 4) ��%�foldSum2(i, 1000, i) ���&�%foldSum2() ��&foldSum2(std::string{"hi"}, "hi", "hi") ���//0/

Nico Josuttis C++17

@MeetingCpp 11/2019 15

Page 16: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4!��$���"�������

template <typename... Args>voidprintAll(Args... args) {(std::cout << ...<< args);

}

voidprint(){}

template <typename T, typename...Types>voidprint(T firstArg, Types...args ){

std::cout <<firstArg<<'\n';

print( args...);

}

std::string str= "world";

print("hi", 7.5, str); �� �C9�5�"�$

=> std::cout << "hi"<< '\n';print(7.5, str);

=> std::cout << "hi" << '\n';std::cout << 7.5 << '\n';print(str);

#�������� ��!� ��,� ��5

std::string str= "world";std::cout <<"hi" <<'';std::cout << 7.5 << '';std::cout << str<< ' ';

std::string str= "world";

printAll("hi", 7.5, str); ��9� �C5�"�$

#�������� ��!� ��,� ��5

std::string str= "world";std::cout <<"hi" <<7.5 << str;

���������� ������ ������ ���� ���

���� 4!��$���"�������

template <typename... Args>voidprintAll(Args... args) {(std::cout << ...<< args)<< '\n';

}

voidprint(){}

template <typename T, typename...Types>voidprint(T firstArg, Types...args ){

std::cout <<firstArg<<'\n';

print( args...);

}

std::string str= "world";

print("hi", 7.5, str); �� �C9�5�"�$

=> std::cout << "hi"<< '\n';print(7.5, str);

=> std::cout << "hi" << '\n';std::cout << 7.5 << '\n';print(str);

#�������� ��!� ��,� ��5

std::string str= "world";std::cout <<"hi" <<'';std::cout << 7.5 << '';std::cout << str<< ' ';

std::string str= "world";

printAll("hi", 7.5, str); ��9� �C5�"�$

#�������� ��!� ��,� ��5

std::string str= "world";std::cout<<"hi"<<7.5<<str<< '\n';

<< '\n'

Nico Josuttis C++17

@MeetingCpp 11/2019 16

Page 17: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4+����!��$���"�������

template<typename... Args>voidprintAll(Args... args) {(std::cout << ...<< args);

}

std::string str= "world";

printAll("hi", 7.5, str); ��9� �C5�"�$

template<typename T>TspaceBefore(T arg){std::cout << ' ';return arg;

}

template<typename First, typename... Args>voidprintSpaced(First arg1, Args... args) {std::cout << arg1;(std::cout << ...<<spaceBefore(args));

}

std::string str= "world";

printSpaced("hi", 7.5, str); ��9� �C5�"�$

#�������� ��!� ��,� ��5

std::string str= "world";std::cout << "hi";std::cout <<spaceBefore(7.5)

<< spaceBefore(str);

����<�9�"���������2

���������� ������ ������ ���� ���

���� 4=�"����$�.������0"$�"

'

'*�����������������"����� 4hi 7.5 worldhi 7.5world

template<typename T>TspaceBefore(T arg){std::cout << ' ';return arg;

}

std::cout << "hi";std::cout <<spaceBefore�7.5)

<<spaceBefore("world");

!���$5��9����

Nico Josuttis C++17

@MeetingCpp 11/2019 17

Page 18: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

H���0��"��"�1��������� 30��"��"������/��"7.4->4[]()

������"� ������� ������ ����� �

�!� �������1�� ���������1����� �+,����������1������ ��������������������1��

++4�--�� ������4��� ������++x��������������x++

-4�!4�~��1���4�67�4���������67�+x� �����,,�����

.*4->*,��������������� ����!� �������1�� ���������1��*4�/4�%�� ��, 4���!���4����� ����������1�� ��,��������������� ���������1�� +4�-���4������� �<<4�>>����������"7�!� �������1�� ���������1��<4�<=4�>=4�> ��������1������������8�� �==4�!=�8�� 4������8�� &��������/60^��������97:|��������7:&& �1� � �/60�!� �������1�� ���������1������� �������false|| �1� � �7:�!� �������1�� ���������1������� �������true=+=4�-=4�*=4����

?:

����1�

��������� ��!� ������

�!� �������1����1������ ���x+=a����8��!� �������x = x+a

��� ��,������;��,�������

,��8��� ������+,���������!� �������1�� ���������1��

����,���

���������� ������ ������ ���� ���

���� 4#9�*�5�"��!��$���"�������

std::string str= "world";

callFoo(42, 7.5, str);

template <typename...Types>void callFoo(const Types&...args){

foo(args...); ������foo(42,7.5,str)foo(args+args...); ������foo(42+42,7.5+7.5,str+str)foo(args)...; ������foo(42)<foo(7.5)<�$foo(str)std::initializer_list<int>{((void)foo(args),0)...}; ��5�"7"���$(...,(void)foo(args));������foo(42),foo(7.5),foo(str)�#$$�%��

}

template <typename...Types>void callFoo(Types&&...args){

(...,(void)foo(std::forward<Types>(args)));��5��9��.��������������"�}

���$���"����������������,������

�//0/

Nico Josuttis C++17

@MeetingCpp 11/2019 18

Page 19: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4+����!��$���"�������5��9auto#������*"����"�

template<typename First, typename... Args>voidprintSpaced(const First& arg1, const Args&... args){std::cout << arg1;autooutWithSpace= [](const auto& arg) {

std::cout << ' '<< arg;};

(...,outWithSpace(args));std::cout << '\n';

}std::string str= "world";

printSpaced("hi", 7.5, str); ��9� �C5�"�$

#�������� ��!� ��,� ��5

std::string str= "world";std::cout << "hi";outWithSpace(7.5),outWithSpace(str);

<���1����� ������,������

(...,outWithSpace(args));

���������� ������ ������ ��� ���

���� 4+����!��$���"�������5��9auto#������*"����"�

template<charsep= ' ',typename First, typename... Types>

voidprint(const First& arg1, const Types&... args){std::cout << arg1;autooutWithSep= [](const auto& arg) {

std::cout << sep<< arg;};

(...,outWithSep(args));��������I��9>��13��"��9$$������"�std::cout << '\n';

}

�����,�����, ����,����������,�

char

std::string str= "world";

print("hi", 7.5, str); ��9� �C5�"�$

print<'-'>("hi", 7.5, str); ��9�; �C;5�"�$

Nico Josuttis C++17

@MeetingCpp 11/2019 19

Page 20: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

���� 4+����!��$���"�������5��9auto#������*"����"�

template<autosep= ' ',typename First, typename... Types>

voidprint(const First& arg1, const Types&... args){std::cout << arg1;autooutWithSep= [](const auto& arg) {

std::cout << sep<< arg;};

(...,outWithSep(args));��������I��9>��13��"��9$$������"�std::cout << '\n';

}

std::string str= "world";

print("hi", 7.5, str); ��9� �C5�"�$

print<'-'>("hi", 7.5, str); ��9�; �C;5�"�$

print<42>("hi", 7.5, str); ��9��% �C�%5�"�$

static const char sep[] = ", ";print<sep>("hi", 7.5, str); ��9�< �C<5�"�$

sep��1�����!�����!� �����, ����,����������,�

auto

�����7����5�����"��$��"��"�������"����������"�������

���������� ������ ������ ���� ���

���� 4+����!��$���"�������5��9auto#������*"����"�

template<autosep= ' ',typename First, typename... Types>

voidprint(const First& arg1, const Types&... args){std::cout << arg1;(...,[](const auto& arg) {

std::cout << sep<< arg;}(args));��������$��"��9$$������"�

std::cout << '\n';}

std::string str= "world";

print("hi", 7.5, str); ��9� �C5�"�$

print<'-'>("hi", 7.5, str); ��9�; �C;5�"�$

print<42>("hi", 7.5, str); ��9��% �C�%5�"�$

static const char sep[] = ", ";print<sep>("hi", 7.5, str); ��9�< �C<5�"�$

sep��1�����!�����!� �����, ����,����������,�

auto

�����7����5�����"��$��"��"�������"����������"�������

Nico Josuttis C++17

@MeetingCpp 11/2019 20

Page 21: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

������J��4>�"����G��5�*"����

����

���������� ������ ������ ���� ���

���� 4�������.�1>��;3>�"���>�"����[1]);

std::vector<std::string> coll;coll.reserve(numElems);for (int i=0; i < numElems/ 2; ++i) {

coll.emplace_back("id"+ std::to_string(i));coll.emplace_back("ID"+ std::to_string(i));

}

sort(coll.begin(), coll.end());

sort(coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return a.substr(2) < b.substr(2);

});now();

����������K

��"�13���4���%%�&

�4���4���%CL�

�����"������4���=��;

�4���4���>%���

',&�$�',� �$&',%�$J �$%',���� �$C

Nico Josuttis C++17

@MeetingCpp 11/2019 21

Page 22: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

����������K

��"�13���4���%%�&

�4���4���%CL�

�����"������4���=��;

�4���4���>%���

���� 4�������.�1>��;3>�"���>�"����[1]);

std::vector<std::string> coll;coll.reserve(numElems);for (int i=0; i < numElems/ 2; ++i) {

coll.emplace_back("id"+ std::to_string(i));coll.emplace_back("ID"+ std::to_string(i));

}

sort(coll.begin(), coll.end());

sort(coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return a.substr(2) < b.substr(2);

});now();

sort(coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return std::string_view{a}.substr(2) < std::string_view{b}.substr(2);

});

����������K

��"�13���4�������

�4���4����=?�%

�����"������4���=��;

�4���4���>%���

��"���.��5���4����)��

�4���4���%���)

',&�$�',� �$&',%�$J �$%',���� �$C

���������� ������ ������ ���� ���

���� 4std::string_view.��std::string

void foo_s(const std::string& s);foo_s("some value");

void foo_v(std::string_viewsv);foo_v("some value"); ��������������9���6

��"���5��"���M.��54

!�� ��� ��@�

��5����5�

�� ��5����5�

��

!�� ��� ��@�

��"���M.��5�"����"���4

��5����5�

��H�5"�4��"���9�����������������9

�����������"������

-����.���-4

��������������9<����������"61����>>03<���6�9"�

����4'����������.�"�����"��string��string_view�"�.�$�$

Nico Josuttis C++17

@MeetingCpp 11/2019 22

Page 23: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

��64

���@�� �

��5����5�

A

��64

���@�� �

��5����5�

A

���� 4��"���M.��5�����$�"�$N"����

std::stringoperator+ (std::string_view sv1, std::string_view sv2) {return std::string{sv1} + std::string{sv2};

}

template<typename T>Tsum (const T& x, const T& y) {

return x + y;}

std::string_viewsv= "hi";autoxy= sum(sv, sv); ��00*>4T�����������������������,���$�$���$�string_viewstd::cout << xy<< '\n'; ��/��;�����//0/1"���"��$�9"��K������"�$6$���"����$3

�.4

��@�

��5����5�

� ��5����5�

A

"��.�4

���������� ������ ������ ��� ���

��64

���@�� �

��5����5�

A

��64

���@�� �

��5����5�

A

���� 4��"���M.��5�����$�"�$N"����

std::stringoperator+ (std::string_view sv1, std::string_view sv2) {return std::string{sv1} + std::string{sv2};

}

template<typename T>autosum (const T& x, const T& y) {

return x + y;}

std::string_viewsv= "hi";autoxy= sum(sv, sv); ��0:4T$�$���$�string_view<���"���"��stringstd::cout << xy<< '\n'; ��0:4���� �,����������""6string"���"��$�6+

�������� �������"���"��6��������, ������auto

�.4

��@�

��5����5�

� ��5����5�

A

"��.�4

Nico Josuttis C++17

@MeetingCpp 11/2019 23

Page 24: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

��64

���@�� �

��5����5�

A

��64

���@�� �

��5����5�

A

���� 4��"���M.��5�����$�"�$N"����

std::stringoperator+ (std::string_view sv1, std::string_view sv2) {return std::string{sv1} + std::string{sv2};

}

template<typename T>autosum (const T& x, const T& y) {

Ttmp = x + y;���return tmp;

}

std::string_viewsv= "hi";autoxy= sum(sv, sv); ��00*>4T�����������������������,���$�$���$�string_viewstd::cout << xy<< '\n'; ��/��;�����//0/1"���"��$�9"��K������"�$6$���"����$3

�.4

��@�

��5����5�

� ��5����5�

A

"��.�4

�������� �������"���"��6��������, ������auto

���������� ������ ������ ���� ���

��64

���@�� �

��5����5�

A

��64

���@�� �

��5����5�

A

���� 4��"���M.��5�����$�"�$N"����

std::stringoperator+ (std::string_view sv1, std::string_view sv2) {return std::string{sv1} + std::string{sv2};

}

template<typename T>autosum (const T& x, const T& y) {

autotmp = x + y;���return tmp;

}

std::string_viewsv= "hi";autoxy= sum(sv, sv); ��0:4T$�$���$�string_view<���"���"��stringstd::cout << xy<< '\n'; ��0:4���� �,����������""6string"���"��$�6+

'�������� �������"���"��6��������, ������auto

'�������� �������"���"��$�6��������, ������auto

�.4

��@�

��5����5�

� ��5����5�

A

"��.�4

Nico Josuttis C++17

@MeetingCpp 11/2019 24

Page 25: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

+����N�"�>����"B�@�������*"�������&���,�5""1���� ����1"."��BAC�

���������� ������ ������ ���� ���

����������K

��"�13���4���%%�&

�4���4���%CL�

�����"������4���=��;

�4���4���>%���

���� 4�������.�1>��;3>�"���>�"����[1]);

std::vector<std::string> coll;coll.reserve(numElems);for (int i=0; i < numElems/ 2; ++i) {

coll.emplace_back("id"+ std::to_string(i));coll.emplace_back("ID"+ std::to_string(i));

}

sort(coll.begin(), coll.end());

sort(coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return a.substr(2) < b.substr(2);

});now();

sort(coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return std::string_view{a}.substr(2) < std::string_view{b}.substr(2);

});

����������K

��"�13���4�������

�4���4����=?�%

�����"������4���=��;

�4���4���>%���

��"���.��5���4����)��

�4���4���%���)

',&�$�',� �$&',%�$J �$%',���� �$C

Nico Josuttis C++17

@MeetingCpp 11/2019 25

Page 26: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

����������K

��"�13���4���%%�&

�4���4���%CL�

�����"������4���=��;

�4���4���>%���

���� 4�������.�1>��;3>�"���>�"����[1]);

std::vector<std::string> coll;coll.reserve(numElems);for (int i=0; i < numElems/ 2; ++i) {

coll.emplace_back("id"+ std::to_string(i));coll.emplace_back("ID"+ std::to_string(i));

}

sort(std::execution::seq,coll.begin(), coll.end());

sort(std::execution::seq,coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return a.substr(2) < b.substr(2);

});now();

sort(std::execution::seq,coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return std::string_view{a}.substr(2) < std::string_view{b}.substr(2);

});

����������K

��"�13���4�������

�4���4����=?�%

�����"������4���=��;

�4���4���>%���

��"���.��5���4����)��

�4���4���%���)

',&�$�',� �$&',%�$J �$%',���� �$C

���������� ������ ������ ���� ���

����������K

��"�13���4�������

�4���4����=?�%

�����"������4���=��;

�4���4���>%���

��"���.��5���4����)��

�4���4���%���)

���� 4�������.�1>��;3>�"���>�"����[1]);

std::vector<std::string> coll;coll.reserve(numElems);for (int i=0; i < numElems/ 2; ++i) {

coll.emplace_back("id"+ std::to_string(i));coll.emplace_back("ID"+ std::to_string(i));

}

sort(std::execution::par,coll.begin(), coll.end());

sort(std::execution::par,coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return a.substr(2) < b.substr(2);

});now();

sort(std::execution::par,coll.begin(), coll.end(),[] (const auto& a, const auto& b) {return std::string_view{a}.substr(2) < std::string_view{b}.substr(2);

});

����������K�"

��"�13���4���������=

�4���4����=?�%����%

�����"������4���=��;�;�=

�4���4���>%����>���

��"���.��5���4����>��)��

�4���4����A��>�C��

',&�$�',� �$&',%�$J �$%',���� �$C

Nico Josuttis C++17

@MeetingCpp 11/2019 26

Page 27: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4*"����*"���>��

std::vector<int> coll{3, 1, 7, 0, 4, 1, 6, 3};

std::partial_sum(coll.begin(), coll.end(), ""����� �std::ostream_iterator<int>(std::cout, " ")); ""������������

std::inclusive_scan(std::execution::par, ""��+� �,� � coll.begin(), coll.end(), ""����� �std::ostream_iterator<int>(std::cout, " ")); ""������������

J����C�L ��%%%C

� & J�L �J

���������� ������ ������ ���� ���

*"����*"���>��DE���scan()

���"

������;�����

���;$�5����

J��� &�C�L ��%%%C%)J� J&�� ��CJ �C

& � J��L ��LJ%CJ& ��� &�C )

� & JCL ���JC%C �� &�� )

� �� JCL �&JC�� �� &%C )

& � �� JCL �%CJC�� �� &)

CL � �� JCL �%CJC�� �� &)

� �� JCL �%CJC�� �� &J� )

� �� JCL ���JC�� �� &�% )

� JCL ��JC�� �� &�� )

� & J�L �JJ%C �� &J )

D��5�E��)��H

������9��FG����+�D��������������/,, � ������H

���,5""��

�� �� �

�����"���" �� ������",���� �"� ���� ",�� � ",�,���"�

�+;�>;�&;��&�9��

Nico Josuttis C++17

@MeetingCpp 11/2019 27

Page 28: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���������4+�����<*��6��"�9���<0.�"��$���@��$�

����

���������� ������ ������ ��� ���

/������*��6��"�9���5��9N������"6

classGeoObj{public:virtual void move(Coord) = 0;virtual void draw() const = 0;virtual~GeoObj() = default;���

};

classCircle: public GeoObj {private:Coord center;int rad;

public:Circle (Coord c, int r);virtual void move(Coord c) override;virtual void draw() const override;

};

classLine: 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::vector<GeoObj*> createFig(){

std::vector<GeoObj*> f;Line*lp= newLine{Coord{1,2}, Coord{3,4}};Circle*cp= newCircle{Coord{5,5}, 7};f.push_back(lp);f.push_back(cp);return f;

}

void drawElems(const std::vector<GeoObj*>& v){

for (GeoObj* gp: v) {gp->draw(); ������$"513����������6��

}}

std::vector<GeoObj*> fig = createFig();drawElems(fig);���

����.��$����"6��7<$�����=��0��B����9�.����"4for (GeoObj*&gp: fig) {

deletegp;gp= nullptr;

}��"���.��������������9�.����"4fig.clear();

@���

=��0��

��"���

Nico Josuttis C++17

@MeetingCpp 11/2019 28

Page 29: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ��� ���

���� 4��������"std::variant<>

#include<variant>

std::variant<int, long, std::string>var; ���������(����"�����"���.�1��$��13DD&3

std::cout << var.index()<< '\n'; ��&std::cout << get<0>(var)<< '\n'; ��&std::cout << get<int>(var)<< '\n'; ��&

var="hello"; ��������"���<��$��13DD%std::cout << var.index()<< '\n'; ��%std::cout << get<2>(var)<< '\n'; ��-9����-std::cout << get<std::string>(var)<< '\n';��-9����-

var=42; ���������<��$��13DD&std::cout << var.index()<< '\n'; ��&

var=77L; ����������<��$��13DD�std::cout << var.index()<< '\n'; ���

std::cout << get<0>(var)<< '\n'; ����$44�$M."���M��������������

std::cout << get<3>(var)<< '\n'; ���������;�����""�"4����9���"���.�std::cout << get<long long>(var)<< '\n';���������;�����""�"4�������������"���.�

."���5��9J-���"���.��-

���������� ������ ������ ���� ���

*��6��"�9���5��9std::variant<>G�����"�

classGeoObj{public:virtual void move(Coord) = 0;virtual void draw() const = 0;virtual~GeoObj() = default;���

};

classCircle: public GeoObj {private:Coord center;intrad;

public:Circle (Coord c, intr);virtual void move(Coord c) override;virtual void draw() const override;

};

classLine: 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::variant<Circle, Line>;

std::vector<GeoObjVar> createFig(){

std::vector<GeoObjVar> f;f.push_back(Line{Coord{1,2}, Coord{3,4}});f.push_back(Circle{Coord{5,5}, 7});return f;

}

void drawElems(const std::vector<GeoObjVar>& v){

for (const GeoObjVar& geoobj: v) {std::visit([] (const auto& obj) {

obj.draw();�����6��"�9�����},geoobj);

}}

std::vector<GeoObjVar> fig = createFig();drawElems(fig);���

��"���.��������������9�.����"4fig.clear();

@���

=��0��

��"���

'���,�������'������"�� ��������,, �� ���'���� ��� � �������1�����

!������������� � � �!��� �

Nico Josuttis C++17

@MeetingCpp 11/2019 29

Page 30: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

!������������� � � �!��� �

*��6��"�9���5��9std::variant<>G�����"�

classCircle{private:Coord center;int rad;

public:Circle (Coord c, int r);void move(Coord c);void draw() const;

};

classLine{private:Coord from;Coord to;

public:Line (Coord f, Coord t);void move(Coord c);void draw() const;

};

using GeoObjVar = std::variant<Circle, Line>;

std::vector<GeoObjVar> createFig(){

std::vector<GeoObjVar> f;f.push_back(Line{Coord{1,2}, Coord{3,4}});f.push_back(Circle{Coord{5,5}, 7});return f;

}

void drawElems(const std::vector<GeoObjVar>& v){

for (const auto& geoobj: v) {std::visit([] (const auto& obj) {

obj.draw();�����6��"�9�����},geoobj);

}}

std::vector<GeoObjVar> fig = createFig();drawElems(fig);���

��"���.��������������9�.����"fig.clear();

'��� ����������� ���'���!����� ���� �����

@���

=��0��

��"���

'���,�������'������"�� ��������,, �� ���'���� ��� � �������1�����

���������� ������ ������ ���� ���

-,�5����-��*��6��"�9���5��9std::variant<>

classCircle{private:Coord center;int rad;

public:Circle (Coord c, int r);void move(Coord c);void draw() const;CoordgetCenter()const;

};

classLine{private:Coord from;Coord to;

public:Line (Coord f, Coord t);void move(Coord c);void draw() const;

};

using GeoObjVar = std::variant<Circle, Line>;

std::vector<GeoObjVar> createFig(){

std::vector<GeoObjVar> f;f.push_back(Line{Coord{1,2}, Coord{3,4}});f.push_back(Circle{Coord{5,5}, 7});return f;

}

void drawElems(const std::vector<GeoObjVar>& v){

for (const GeoObjVar& geoobj: v) {std::visit([] (const auto& obj) {

obj.draw();""�,� ���,�� � � },geoobj);

��$�5������"."���4if (auto goPtr= std::get_if<Circle>(&geoobj);goPtr){

std::cout << goPtr->getCenter() << '\n';}

}}

@���

=��0��

��"���

Nico Josuttis C++17

@MeetingCpp 11/2019 30

Page 31: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

-,�5����-��*��6��"�9���5��9std::variant<>

classCircle{private:Coord center;int rad;

public:Circle (Coord c, int r);void move(Coord c);void draw() const;CoordgetCenter()const;

};

classLine{private:Coord from;Coord to;

public:Line (Coord f, Coord t);void move(Coord c);void draw() const;

};

using GeoObjVar = std::variant<Circle, Line>;

std::vector<GeoObjVar> createFig(){

std::vector<GeoObjVar> f;f.push_back(Line{Coord{1,2}, Coord{3,4}});f.push_back(Circle{Coord{5,5}, 7});return f;

}

void drawElems(const std::vector<GeoObjVar>& v){

for (const GeoObjVar& geoobj: v) {std::visit([] (const auto& obj) {

obj.draw();""�,� ���,�� � � ��$�5��������$�.�����"4if constexpr(std::is_same_v<decltype(obj),

const Circle&>) {std::cout << obj.getCenter() << '\n';

}},geoobj);

}}

@���

=��0��

��"���

���������� ������ ������ ���� ���

-,�5����-��*��6��"�9���5��9std::variant<>

classCircle{private:Coord center;int rad;

public:Circle (Coord c, int r);void move(Coord c);void draw() const;CoordgetCenter()const;

};

classLine{private:Coord from;Coord to;

public:Line (Coord f, Coord t);void move(Coord c);void draw() const;

};

using GeoObjVar = std::variant<Circle, Line>;

std::vector<GeoObjVar> createFig(){

std::vector<GeoObjVar> f;f.push_back(Line{Coord{1,2}, Coord{3,4}});f.push_back(Circle{Coord{5,5}, 7});return f;

}

void drawElems(const std::vector<GeoObjVar>& v){

for (const GeoObjVar& geoobj: v) {std::visit(Ovld{[](constauto& obj) {

obj.draw();},

[](constCircle& c) {c.draw();std::cout << c.getCenter() << '\n';

}},

geoobj);}

}

@���

=��0��

��"���

template<typename... Functors>structOvld: Functors... {using Functors::operator()...;

};��$�$����������"��������"���������(�"�4template<typename... Functors> Ovld(Functors...) -> Ovld<Functors...>;

Ovld<���>

[](const auto&) {���

}

[](const Circle&) {���

}

���� !���"��4'std::variant<>'/11��1�������������� �����'0��� �����1�����'-������ �using

+�����"���9��������""�"9�"�

Nico Josuttis C++17

@MeetingCpp 11/2019 31

Page 32: Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚ ˙" > "˚˜ ˘˙ ˙˚ template  void

���������� ������ ������ ���� ���

���� 4>���"6

'������5�����4&if����������� �.�����&#��,� �������if&std::variant&#�/0&0��� �����1�����&C� ���+,��������&G��� � �D�I&��������1��11��1����&<������������� �.��������1����&D����1�!����&C�+��1��!� ������������&D �,��� � 3�&auto���������1�� ����� ��������, ����,���������&����������9�������"��

��������������$������ �������

�$�"��4

���������� ������ ������ ���� ���

#9�7O��2

'������5������$�"��

'�6���7���"���� 4

&C++ Templates -The Complete Guide'�������7����

&C++17 –The Complete Guide '�����$� ����

��������������$������ �������

Nico Josuttis C++17

@MeetingCpp 11/2019 32