c++17

Overloading structs with template call operator and generic lambdas - gcc vs clang

懵懂的女人 提交于 2019-11-30 12:17:45
I have discovered a code snippet that compiles and works properly in clang++ 4 (and trunk) but fails to compile in g++ 7 (and trunk) . Let's assume I have the following struct types: struct a { void foo() { } }; struct b { void bar() { } }; struct c { void bar() { } }; I want to create an overload set out of lambdas which handles a explicitly, while b and c are "caught" with a generic lambda using an auto parameter: auto ol = overload([](a x) { x.foo(); }, [](auto x){ x.bar(); }) When I invoke ol(a{}) : clang++ compiles and behaves as expected: a "matches" the first lambda, while b and c match

Why does moving std::optional not reset state

…衆ロ難τιáo~ 提交于 2019-11-30 11:03:21
I was rather surprised to learn that the move constructor (and assignment for that matter) of std::optional does not reset the optional moved from, as can be seen in [19.6.3.1/7] which states "bool(rhs) is unchanged." This can also be seen by the following code: #include <ios> #include <iostream> #include <optional> #include <utility> int main() { std::optional<int> foo{ 0 }; std::optional<int> bar{ std::move(foo) }; std::cout << std::boolalpha << foo.has_value() << '\n' // true << bar.has_value() << '\n'; // true } This seems to contradict other instances of moving in the standard library

May I change the held type in a std::variant from within a call to std::visit

折月煮酒 提交于 2019-11-30 10:59:43
Does the following code invoke undefined behaviour? std::variant<A,B> v = ...; std::visit([&v](auto& e){ if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>) e.some_modifying_operation_on_A(); else { int i = e.some_accessor_of_B(); v = some_function_returning_A(i); } }, v); In particular, when the variant does not contain an A , this code re-assigns an A while still holding a reference to the previously held object of type B . However, because the reference is not used anymore after the assignment, I feel the code is fine. However, would a standard-library be free to implement

How to enable C++17 in CMake

放肆的年华 提交于 2019-11-30 10:46:37
I'm using VS 15.3, which supports integrated CMake 3.8. How can I target C++17 without writing flags for each specific compilers? My current global settings don't work: # https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # expected behaviour #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++lastest") I expected CMake to add "/std:c++lastest" or equivalents when generating VS solution files, but no c++17 flags was found, resulted in compiler error: C1189 #error: class template optional is

How do I build gcc with C++ concepts (“concepts lite”) support?

烂漫一生 提交于 2019-11-30 10:45:28
The C++ standards committee is working on a TS (Technical Specification) for Concepts extension: "Programming Languages - C++ Extensions for Concepts". N4377 is the latest version of this document. For inclusion into the C++ standard features are asked to be implemented, ideally for a publicly accessible system. I'm aware of concept-gcc but the concepts proposal above (colloquially referred to as Concepts Lite ) is different. I heard that there is a concepts branch and I have tried the origin/asutton/c++-concepts from gcc 's git mirror but that didn't compile. How do I build and use a version

C++ parameter pack with single type enforced in arguments

南笙酒味 提交于 2019-11-30 09:23:40
I want to be able to do the following: #include <array> struct blah { }; template<typename... Args> constexpr auto foo(Args&&... args) { return std::array<blah, sizeof...(Args)>{{ args... }}; } auto res = foo({}, {}); The following answers aren't satisfying: they just want to check that the parameter pack is of a single type, but I want to convert the values right to it in the arguments (else it does not work). C++ parameter pack, constrained to have instances of a single type? Parameter with non-deduced type after parameter pack Specifying one type for all arguments passed to variadic

constexpr and std::cout working on function but not in lambda

六眼飞鱼酱① 提交于 2019-11-30 09:20:41
Why constexpr does not work with std::cout , but works with printf ? #include <iostream> constexpr void f() { std::cout << ""; } //error constexpr void g() { printf(""); } //ok And why std::cout works with lambdas constexpr ? #include <iostream> int main () { auto h = []() constexpr { std::cout << ""; }; //ok } Technically, it doesn't work with any of them. From [dcl.constexr] : For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a

Why std::function::argument_type has been deprecated?

青春壹個敷衍的年華 提交于 2019-11-30 08:55:33
问题 I've seen on cppreference that std::function::argument_type was deprecated in C++17. What is the reason behind it? And what ISO WG21 paper was proposing that? 回答1: The relevant papers are P0005R4 (which is the paper that was voted into the draft standard) and P0090R0 (which is referenced by P0005R4). Quotes from P0090R0: Q2. What's wrong with result_type, etc.? A2. These C++98/03/TR1-era typedefs predated decltype and perfect forwarding. Previously, generic code had to request information

reinterpret_cast, char*, and undefined behavior

岁酱吖の 提交于 2019-11-30 08:41:14
What are the cases where reinterpret_cast ing a char* (or char[N] ) is undefined behavior, and when is it defined behavior? What is the rule of thumb I should be using to answer this question? As we learned from this question , the following is undefined behavior: alignas(int) char data[sizeof(int)]; int *myInt = new (data) int; // OK *myInt = 34; // OK int i = *reinterpret_cast<int*>(data); // <== UB! have to use std::launder But at what point can we do a reinterpret_cast on a char array and have it NOT be undefined behavior? Here are a few simple examples: No new , just reinterpret_cast :

What changes to C++ made copy initialization work for class with explicit constructor?

蓝咒 提交于 2019-11-30 08:20:34
Consider this code: struct X{ explicit X(){} explicit X(const X&){} }; void foo(X a = X()){} int main(){} Using C++14 standard, both GCC 7.1 and clang 4.0 rejects the code, which is what I expected. However, using C++17 ( -std=c++1z ), they both accept the code. What rule changed? For both compilers to exhibit this same behavior, I doubt this to be a bug. But as far as I can tell, the latest draft still says, default argument uses the semantics of copy-initialization 1 . Again, we know that explicit constructors will only allow direct initialization 2 . 1 : dcl.fct.default/5 ; 2 : class.conv