Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚...
Transcript of Combining C++17 Features+17_191114.pdf · ˘ˇ ˆ˙ 4 if < if < #" < ˚$ = "$ =˙˚˙"! ˚ ˚ ’˚...
���������� ������ ������ �� ����
�������� �������������������
����� �������
�����
�������������������
���� !���"��
���������� ������ ������ �� ����
���#����"��
��������
��$�"����
���%&�������
����
Nico Josuttis C++17
@MeetingCpp 11/2019 1
���������� ������ ������ ��� ���
'������(����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
���������� ������ ������ ��� ���
���������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
���������� ������ ������ ��� ���
=���"��!���������'���"�>�"����������
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
���������� ������ ������ ��� ���
=���"��!���������'���"�>�"����������
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
���������� ������ ������ ���� ���
=���"��!���������'���"�>�"����������
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
���������� ������ ������ ���� ���
+����@��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
���������� ������ ������ ���� ���
+����@��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
���������� ������ ������ ���� ���
=���"��!���������'���"�>�"����������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
���������� ������ ������ ��� ���
=���"��!���������'���"�>�"����������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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ���� ���
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
���������� ������ ������ ��� ���
���� 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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ���� ���
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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ��� ���
���� 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
���������� ������ ������ ���� ���
������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
���������� ������ ������ ���� ���
����������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
���������� ������ ������ ���� ���
��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
���������� ������ ������ ��� ���
��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
���������� ������ ������ ���� ���
+����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
���������� ������ ������ ���� ���
����������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
���������� ������ ������ ���� ���
���� 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
���������� ������ ������ ���� ���
���������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
���������� ������ ������ ��� ���
���� 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
���������� ������ ������ ���� ���
!������������� � � �!��� �
*��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
���������� ������ ������ ���� ���
-,�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
���������� ������ ������ ���� ���
���� 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