c++17

Are fold expressions subject to short-circuiting?

守給你的承諾、 提交于 2019-12-01 19:00:55
In C++17, are fold expressions subject to short-circuiting when used with && or || as their operator? If so, where is this specified? Yes, fold expressions using && or || as the operator can short-circuit, subject to the usual caveat that it happens for the built-in meaning, but not for an overloaded operator function. The meaning of a fold-expression is defined in [temp.variadic]/9: The instantiation of a fold-expression produces: ((E_1 op E_2) op ... ) op E_N for a unary left fold, E_1 op ( ... op (E_N_minus_1 op E_N)) for a unary right fold, (((E op E_1) op E_2) op ... ) op E_N for a binary

why are virtual base non-default constructors not called unless most-derived base explicitly invokes them?

邮差的信 提交于 2019-12-01 18:45:54
I would like to understand WHY C++ standard mandates that virtual base non-default constructors cannot be invoked by an intermediate NOT most-derived class, as in this code, when compiled with '-D_WITH_BUG_' : /* A virtual base's non-default constructor is NOT called UNLESS * the MOST DERIVED class explicitly invokes it */ #include <type_traits> #include <string> #include <iostream> class A { public: int _a; A(): _a(1) { std::cerr << "A() - me: " << ((void*)this) << std::endl; } A(int a): _a(a) { std::cerr << "A(a) - me:" << ((void*)this) << std::endl; } virtual ~A() { std::cerr << "~A" << (

Expanding parameter pack into lambda with fold expression - gcc vs clang

依然范特西╮ 提交于 2019-12-01 17:20:16
Considering the following code snippet: template <typename TF> void post(TF){ } template <typename... TFs> struct funcs : TFs... { funcs(TFs... fs) : TFs{fs}... { } void call() { (post([&]{ static_cast<TFs&>(*this)(); }), ...); } }; clang++ 3.8+ successfully compiles the code . g++ 7.0 fails to compile with the following error: prog.cc: In lambda function: prog.cc:10:43: error: parameter packs not expanded with '...': (post([&]{ static_cast<TFs&>(*this)(); }), ...); ~~~~~~~~~~~~~~~~~~~~~~~~^~ prog.cc:10:43: note: 'TFs' prog.cc: In member function 'void funcs<TFs>::call()': prog.cc:10:13: error

How can this code be constexpr? (std::chrono)

雨燕双飞 提交于 2019-12-01 16:56:50
In the standards paper P0092R1, Howard Hinnant wrote: template <class To, class Rep, class Period, class = enable_if_t<detail::is_duration<To>{}>> constexpr To floor(const duration<Rep, Period>& d) { To t = duration_cast<To>(d); if (t > d) --t; return t; } How can this code work? The problem is that operator-- on a std::chrono::duration is not a constexpr operation. It is defined as: duration& operator--(); And yet this code compiles, and gives the right answer at compile time: static_assert(floor<hours>(minutes{3}).count() == 0, "”); What's up with that? The answer is that not all operations

What are the types of identifiers introduced by structured bindings in C++17?

前提是你 提交于 2019-12-01 16:56:00
To my knowledge, identifiers introduced by structured bindings in C++17 are in fact references to some "hidden" variable. Such that auto [ a, b ] = std::make_tuple(1, 2); is kind-of equivalent to auto e = std::make_tuple(1, 2); auto& a = std::get<0>(e); auto& b = std::get<1>(e); However, if I print out std::is_reference<decltype(a)>::value , I get 0 in the first case 1 in the second. Why is that? if I print out std::is_reference<decltype(a)>::value , I get 0 in the first case 1 in the second. Why is that even if we can prove that a and b refer to the elements in the tuple and one can modify

Why is sizeof(std::variant) the same size as a struct with the same members?

廉价感情. 提交于 2019-12-01 16:54:17
问题 The class template std::variant represents a type-safe union. An instance of std::variant at any given time either holds a value of one of its alternative types, or it holds no value. sizeof(std::variant<float, int32_t, double>) == 16 But if it is a union, why does it take so much space? struct T1 { float a; int32_t b; double c; }; struct T2 { union { float a; int32_t b; double c; }; }; The variant has the same size as the struct sizeof(T1) == 16 sizeof(T2) == 8 I would expect the size of the

Static member access in constant expressions

十年热恋 提交于 2019-12-01 16:01:18
Accessing static class member functions or variables, can be done in two ways: through an object ( obj.member_fun() or obj.member_var ) or through the class ( Class::member_fun() or Class::member_var ). However, in constexpr functions, Clang gives an error on the object access and requires to use class access: struct S { constexpr static auto s_v = 42; constexpr static auto v() { return s_v; } }; #define TEST 1 constexpr auto foo(S const& s [[maybe_unused]]) { #if TEST constexpr auto v = s.v(); // ERROR for clang, OK for gcc #else constexpr auto v = S::v(); // OK for clang and gcc #endif

Understand structured binding in C++17 by analogy

孤人 提交于 2019-12-01 15:54:17
I'm trying to understand structured binding introduced in C++17. The explanation on cppreference is not obvious to me, but it looks like cv-auto ref-operator [x, y, z] = ... is roughly equivalent to (not to consider array case) cv-auto ref-operator unique_name = ... #define x unique_name.member_a #define y unique_name.member_b #define z unique_name.member_c The key point here is that x y z are not independently defined variables, but just aliases of the return value members. And cv-auto ref-operator applies to the return value, not the aliases (the syntax may be misleading here). For instance,

Structured binding and tie()

人走茶凉 提交于 2019-12-01 15:43:52
Given these declarations: int a[3] {10,20,30}; std::tuple<int,int,int> b {11,22,33}; I can use structured binding declarations to decode a and b : auto [x1,y1,z1] = a; auto [x2,y2,z2] = b; But if x1 , y1 , etc. already exist, what do I do? std::tie(x1,y1,z1) = a; // ERROR std::tie(x2,y2,z2) = b; // OK This works for b but not for a . Is there a similar simple construct that works for a , or do I have to fetch a[0] , a[1] and a[2] separately? Nope. Structured bindings has specific language rules to handle arrays and certain other types. tie() is specifically a tuple<T&...> and can only be

std::visit for variant fails to compile under clang 5 [duplicate]

余生颓废 提交于 2019-12-01 15:30:18
This question already has an answer here: get<string> for variants fail under clang++ but not g++ 1 answer The following uses of std::visit compiles properly under gcc 7.2 but fails to compile under clang 5.0. Does anyone know what the problem is? #include <variant> struct S1 {int foo() { return 0; }}; struct S2 {int foo() { return 1; }}; using V = std::variant<S1, S2>; int bar() { V v; return std::visit([](auto& s) { return s.foo(); }, v); } The first error is this: include/c++/7.2.0/variant:238:46: error: cannot cast 'std::variant<S1, S2>' to its private base class 'std::__detail::__variant: