C++ features by examples
17.cpp
Go to the documentation of this file.
1
15static_assert(__cplusplus == 201703);
16
17#include <bits/stdc++.h>
18
19using namespace std;
20
40constexpr pair deducted_pair(1, 2.3);
41static_assert(deducted_pair.second == 2.3);
42
44constexpr tuple deducted_tuple(4, 2, 2.5);
45static_assert(get<2>(deducted_tuple) == 2.5);
46
48template <typename T = float>
50 T val;
53};
54
57
58#if __cpp_deduction_guides > 201611
59
61template_struct template_default_arg_deduction;
62
63#endif
64
65vector<int> int_vector = {1, 2, 3, 4};
66
68
71
74
76array deduction_guide_array {1, 2, 3, 4};
77
83
84
90{
91 assert(deduction_guide1_queue[0] == 1);
92 assert(*deduction_guide2_queue[0] == 1);
93 assert(deduction_guide1_vector[0] == 1);
94 assert(*deduction_guide2_vector[0] == 1);
95}
96
105template<auto n> struct B { /* ... */ };
106
107B<5> b1; // OK: non-type template parameter type is int
108
110
111// Error:
112// B<2.5> b3;
113
114tuple<int, int> foo_tuple()
115{
116 // return make_tuple(1, -1);
117 return {1, -1};
118}
119
120template <auto... seq>
122};
123
126
147// explicit constexpr
148auto identity = [](int n) constexpr { return n; };
149static_assert(identity(1) == 1);
150
151// lambda with auto argument actually is a template
152
153// implicit auto constexpr:
154
155auto can_be_constexpr1 = [](auto a) { return a; };
156auto can_be_constexpr2 = [](int(*fp)(int), auto a) { return fp(a); };
157
158static_assert(can_be_constexpr2(can_be_constexpr1, 3) == 3);
159
160// error: non-constant condition for static assertion
161// static int i=0;
162// static_assert(can_be_constexpr2(can_be_constexpr1, i) == 0);
163
164auto non_const = [](auto a) {static int s; return a; };
165
166// error: no specialization can be constexpr because of s
167// static_assert(can_be_constexpr(non_const, 3)==3);
168
169constexpr int const_inc(int n)
170{
171 return [n] { return n + 1; }();
172}
173
174constexpr int(*inc)(int) = const_inc;
175static_assert(const_inc(1) == 2);
176
188{
189 struct capture_value_o {
190 int value {1};
191 auto get_value_copy() {
192 return [*this] { return value; };
193 }
194 };
195
196 capture_value_o mo;
197 auto val = mo.get_value_copy();
198 mo.value = 2;
199 assert(val() == 1);
200}
201
203{
204 assert(can_be_constexpr1(2) == 2);
205 int i = 3;
206 assert(can_be_constexpr2(can_be_constexpr1, 3) == 3);
207 non_const(1);
209}
210
211
212
232{
233 shared_mutex m;
234 shared_lock lock(m);
235
236 mutex mt[2];
237 thread t2;
238 {
239 scoped_lock l1(mt[0], mt[1]);
240 t2 = thread([&mt]{
241 scoped_lock l2(mt[0], mt[1]);
242 });
243 }
244 t2.join();
245
246}
247
249
257{
258 static_assert(is_reference_v<int&>);
259
260 // L-value:
261 static_assert(is_lvalue_reference_v<int&>);
262
263 // R-value
264 static_assert(is_rvalue_reference_v<int&&>);
265}
266
273template<typename... Args>
274constexpr bool folding_and(Args... args) { return (true && ... && args); }
275
276template<typename... Args>
277constexpr auto folding_sum(Args... args) { return (... + args); }
278
280{
281 static_assert(!folding_and(true, false, true));
282 static_assert(folding_sum(1.0, 2.0f, 3) == 6.0);
283}
284
296
298{
300}
301
310static_assert(__cpp_structured_bindings);
311
313{
314
315 int a[2] = {1, 2};
316
317 auto [a0, a1] = a;
318 // a0_ref = &a; a0_ref = &a;
319 auto& [a0_ref, a1_ref] = a;
320
321 float x{};
322 char y{};
323 int z{};
324
325 unordered_map<string, int> mapping {
326 {"a", 1},
327 {"b", 2},
328 {"c", 3},
329 };
330
331 for (const auto& [key, value] : mapping) {
332 // Do something with key and value
333 }
334 //tuple<float&,char&&,int> tpl(x,move(y),z);
335 //const auto& [a,b,c] = tpl;
336 // https://en.cppreference.com/w/cpp/language/structured_binding
337 auto [min, max] = minmax({3, 2, 1});
338 assert(min == 1);
339 assert(max == 3);
340}
341
342
344
354{
355 if (auto a = true) {
356 };
357
358 switch (int a = 10) {
359 }
360}
361
372// Will warn if return of foo() is ignored
373[[nodiscard]] int foo() {return 0;}
375{
376 int a {1};
377 switch (a) {
378 // Indicates that falling through on case 1 is intentional
379 case 1:
380 [[fallthrough]];
381 case 2:
382 // Indicates that b might be unused, such as on production builds
383 [[maybe_unused]] int b = foo();
384 assert(b > 0);
385 break;
386 }
387}
388
390
396constexpr int const_if()
397{
398 if constexpr(true)
399 return 1;
400}
401
402static_assert(const_if());
403
410static char char_u8 = u8'x';
411
421{
422 enum byte_e : unsigned char {};
423 static byte_e b { 123 };
424
425floating_literal:
426 static_assert(is_integral_v<int>);
427 static_assert(__cpp_hex_float);
428 double hex_double = 0x1.2p3;
429 assert(hex_double == 9.0);
430
431 static_assert(is_invocable<decltype(types_17)>::value);
432 static_assert(is_invocable<int()>::value);
433 static_assert(is_invocable_r<int, int()>::value);
434 static_assert(is_invocable_r<void, void(int), int>::value);
435 static_assert(negation_v<bool_constant<false>>);
436
437 auto inc = [](int a) -> int { return a + 1; };
438 static_assert(is_invocable_r<int, decltype(inc), int>::value);
439 static_assert(__cpp_lib_invoke);
440 assert(invoke(inc, 2) == 3);
441}
442
443
453{
455 map<int, string> m{{1, "mango"}, {2, "papaya"}, {3, "guava"}};
456 auto nh = m.extract(2);
457 nh.key() = 4;
459 m.insert(move(nh));
460 // m == {{1, "mango"}, {3, "guava"}, {4, "papaya"}}
461
463 set<int> src {1, 3, 5};
464 set<int> dst {2, 4, 5};
465 dst.merge(src);
466 // src == { 5 }
467 // dst == { 1, 2, 3, 4, 5 }
468}
469
477{
478 variant<int, float> v, w;
479 v = 12; // v contains int
480 int i = get<int>(v);
481 w = get<int>(v);
482 w = get<0>(v); // same effect as the previous line
483 w = v; // same effect as the previous line
484