c++17

Return type std::optional<std::variant<…>>

我怕爱的太早我们不能终老 提交于 2019-12-05 05:36:24
I have a situation where a function must return a value taken from a table. A cell in this table (let's assume the table just works...) may contain a value, or it might not. This value can also be one of several types: int, double, string, date (but no other type). What would such a function return? Is it a good idea to return std::optional<std::variant<std::string, int, double, std::chrono::time_point>> ? Would that be a good use of optional and variant ? I would consider this to be a useful use of std::monostate . Specifically, variant<std::monostate, int, double, std::string, std::chrono:

Unpacking a typelist

夙愿已清 提交于 2019-12-05 04:45:42
Lets say I have a function that takes just a type template parameter, I cannot change it's definition/implementation. template < typename T > void do_it(); Now I have a typelist defined a usual way, can't change it either: template< typename ...Ts > struct typelist; I want to implement a function that takes a typelist, and runs do_it() on every type: template< typename List > void do_them(); The only solution I found up 'till now is: template< typename T > void do_them_impl() { do_it<T>(); } template< typename T, typename Ts...> void do_them_impl() { do_it<T>(); do_them_impl<Ts...>(); }

Could not convert from brace-enclosed initializer list to std tuple

醉酒当歌 提交于 2019-12-05 04:35:57
As part of a bigger project, I'm playing with std::tuple and templates; consider the following code: template <typename ...T> void foo(tuple<T...> t) {} void bar(tuple<int, char> t) {} tuple<int, char> quxx() { return {1, 'S'}; } int main(int argc, char const *argv[]) { foo({1, 'S'}); // error foo(make_tuple(1, 'S')); // ok bar({1, 'S'}); // ok quxx(); // ok return 0; } According to this answer C++17 supports tuple initialization from copy-list-initialization , however it seems such support is limited since I get the following error (GCC 7.2.0): main.cpp: In function 'int main(int, const char*

Hashing types at compile-time in C++17/C++2a

半腔热情 提交于 2019-12-05 04:29:12
Consider the following code: #include <iostream> #include <type_traits> template <class T> constexpr std::size_t type_hash(T) noexcept { // Compute a hash for the type // DO SOMETHING SMART HERE } int main(int argc, char* argv[]) { auto x = []{}; auto y = []{}; auto z = x; std::cout << std::is_same_v<decltype(x), decltype(y)> << std::endl; // 0 std::cout << std::is_same_v<decltype(x), decltype(z)> << std::endl; // 1 constexpr std::size_t xhash = type_hash(x); constexpr std::size_t yhash = type_hash(y); constexpr std::size_t zhash = type_hash(z); std::cout << (xhash == yhash) << std::endl; //

Do std::tuple and std::pair support aggregate initialization?

百般思念 提交于 2019-12-05 04:07:21
Aggregate initialization requires among other things no user-provided constructors . But std::tuple and std::pair pair have a large set of overloaded constructors . From the point of the core language, are these constructors user-provided or even user-declared ? With C++17 it will be possible to write (update/clarification: where nocopy is a class that can not be copied or moved, such as std::mutex ) auto get_ensured_rvo_str(){ return std::pair(std::string(),nocopy()); } edit: no, it's not possible as explained in the linked to answers and the answer below. which requires aggregate

Using std::launder to get a pointer to an active union member from a pointer to an inactive union member?

别说谁变了你拦得住时间么 提交于 2019-12-05 03:57:58
Consider this union: union A{ int a; struct{ int b; } c; }; c and a are not layout-compatibles types so it is not possible to read the value of b through a : A x; x.c.b=10; x.a+x.a; //undefined behaviour (UB) For Trial 1 and Trial 2 see this question Trial 3 Now let's use std::launder for what it does not seems to be intended: A x; x.a=10; auto p = &x.a; //(1) x.c.b=12; //(2) p = std::launder(p); //(2') *p+*p; //(3) UB? Could std::launder change anything? According to [ptr.launder] : template <class T> constexpr T* launder(T* p) noexcept; Requires : p represents the address A of a byte in

Are function attributes inherited?

孤街浪徒 提交于 2019-12-05 03:31:34
If I have a virtual function that carries an attribute [[nodiscard]] virtual bool some_function() = 0; Does that attribute get implicitly applied to overrides of that function? bool some_function() override; Or do I need the attribute again? [[nodiscard]] bool some_function() override; I can't see any evidence in the C++17 wording that attributes are inherited by overriding functions. The most relevant section I can find is the rules for overriding: [class.virtual]/2: If a virtual member function vf is declared in a class Base and in a class Derived , derived directly or indirectly from Base ,

deduction guides and injected class names

*爱你&永不变心* 提交于 2019-12-05 03:09:37
template <typename T> struct X { template <typename Iter> X(Iter a, Iter b) {} template <typename Iter> auto f(Iter a, Iter b) { return X(a, b); } }; In the "C++ Templates, The Complete Guide" 2nd edition, there was the previous example about the subtitles of implicit deduction guides with injected class names. The author mentioned that class argument deduction is disabled for injected class names because the type of the return of f would be X<Iter> due to the implicit deduction guide. But I believe the implicit deduction guide for a template constructor would rather look like the one below.

Can std::launder be used to convert an object pointer to its enclosing array pointer?

吃可爱长大的小学妹 提交于 2019-12-05 03:07:31
The current draft standard (and presumably C++17) say in [basic.compound/4] : [ Note: An array object and its first element are not pointer-interconvertible, even though they have the same address. — end note ] So a pointer to an object cannot be reinterpret_cast 'd to get its enclosing array pointer. Now, there is std::launder , [ptr.launder/1] : template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept ; Requires: p represents the address A of a byte in memory. An object X that is within its lifetime and whose type is similar to T is located at the address A. All bytes of storage

Should args to inherited constructors be copied when invoking the base ctor or not?

陌路散爱 提交于 2019-12-05 02:52:58
问题 For the following program: #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } ~Foo() { std::cout << "~Foo()\n"; } }; struct A { A(Foo) {} }; struct B : A { using A::A; }; int main() { Foo f; B b(f); } GCC gives: $ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out Foo() Foo(const Foo&) ~Foo() ~Foo() VS 2017 (also in C++17 mode) gives: Foo() Foo(const Foo&) Foo(const Foo&) ~Foo() ~Foo() ~Foo() Who's right, and