c++17

initializer_list with auto contains multiple expressions

谁都会走 提交于 2019-12-05 09:26:41
问题 Rather simple question, auto x11 {1,2,3,4}; auto x1 = {1,2,3,4}; auto x22 {1.0, 2.25, 3.5}; auto x2 = {1.0, 2.25, 3.5}; As far as I understand, there should be no difference here with respect to having = or not. However, using llvm/clang 6.0.0 (with --std=c++17), I get : main1.cpp:35:17: error: initializer for variable 'x11' with type 'auto' contains multiple expressions auto x11 {1,2,3,4}; ~~~~~~~~ ^ main1.cpp:37:20: error: initializer for variable 'x22' with type 'auto' contains multiple

Intriguing assembly for comparing std::optional of primitive types

点点圈 提交于 2019-12-05 09:18:56
问题 Valgrind picked up a flurry Conditional jump or move depends on uninitialised value(s) in one of my unit tests. Inspecting the assembly, I realized that the following code: bool operator==(MyType const& left, MyType const& right) { // ... some code ... if (left.getA() != right.getA()) { return false; } // ... some code ... return true; } Where MyType::getA() const -> std::optional<std::uint8_t> , generated the following assembly: 0x00000000004d9588 <+108>: xor eax,eax 0x00000000004d958a <+110

Visual Studio not performing RVO when ternary operator is used and move/copy ctors are deleted

淺唱寂寞╮ 提交于 2019-12-05 09:02:53
Looking at below code sample I would expect it to perform mandatory copy elision as part of Return Value Optimization (RVO) and compile with C++17 (/std:c++17) but it compiles with an error on Visual Studio 2017 (I'm using VS17, 15.9.8 more specifically). class NoCopyOrMove { public: NoCopyOrMove() = default; NoCopyOrMove(int a, int b){} NoCopyOrMove(const NoCopyOrMove&) = delete; NoCopyOrMove& operator=(const NoCopyOrMove&) = delete; NoCopyOrMove(NoCopyOrMove&&) = delete; NoCopyOrMove& operator=(NoCopyOrMove&&) = delete; private: int a, b; }; NoCopyOrMove get(bool b) { return b ? NoCopyOrMove

Is decltype(auto) for a structured binding supposed to be a reference?

纵饮孤独 提交于 2019-12-05 08:51:08
问题 Consider an example: #include <iostream> #include <type_traits> #include <tuple> int main() { auto tup = std::make_tuple(1, 2); auto [ a, b ] = tup; decltype(auto) e = a; std::cout << std::boolalpha << std::is_reference_v<decltype(e)> << std::endl; } clang (output: false ) and gcc (output: true ) are disagreeing in this simple case. Having in mind e.g. this Q&As should the e be a reference or is it a gcc bug? Or maybe the code is ill-formed? 回答1: The identifers themselves are references. From

Initializer “sizeof(T)” of inline static auto… Does it need instantiation?

為{幸葍}努か 提交于 2019-12-05 08:37:17
What should happen if an expression's type is not dependent, but we use it to initialize a static auto variable? GCC and Clang differ in their behavior template<typename T> struct A { static inline auto x = sizeof(T{}.f); }; A<int> a; GCC doesn't raise an error. But Clang thinks that this is invalid because it instantiates the operand of "sizeof". GCC appears to skip that step because sizeof(T{}.f) always has type size_t (not type dependent), so it already knows type of x without instantiation. Both compilers conformly reject the program if we refer to x , for example by (void) a.x; . Does it

Why can't decomposition declarations be constexpr?

余生长醉 提交于 2019-12-05 08:27:13
问题 Consider the following snippet to test the upcoming C++17 feature decomposition declarations (formerly known as structured bindings) #include <cassert> #include <utility> constexpr auto divmod(int n, int d) { return std::make_pair(n / d, n % d); // in g++7, also just std::pair{n/d, n%d} } int main() { constexpr auto [q, r] = divmod(10, 3); static_assert(q == 3 && r ==1); } This fails on both g++7-SVN and clang-4.0-SVN with the message: decomposition declaration cannot be declared 'constexpr'

Comparison for objects derived from std::string_view is ambiguous in MSVC

旧巷老猫 提交于 2019-12-05 07:50:46
TL;DR: Can I expect that the code below will compile on any c++17 conformant c++ toolchain (based on the current c++17 proposal) and the failure of MSVC to do so is a bug in their implementation? #include <string_view> struct Foo : std::string_view {}; int main() { Foo f1{}; Foo f2{}; return f1 == f2; } Explanation: I have a class that is derived from std::string_view and doesn't implement its own comparison operators, because the std::string_view semantics are exactly what I need and I also want it to be comparable to e.g. a std::string . However, if I try to compare two instances of that

experimental::optional nullopt_t constructor

无人久伴 提交于 2019-12-05 07:03:31
Here is described the nullopt_t and nullopt for the optional object proposed for c++: struct nullopt_t{see below}; constexpr nullopt_t nullopt(unspecified); [...] Type nullopt_t shall not have a default constructor. It shall be a literal type. Constant nullopt shall be initialized with an argument of literal type. The reason for this is explained in the The op = {} syntax chapter of the document: for the op = {} to be unambiguous some tricks have to be adopted, one of which is that nullopt_t must not be default constructible. My question is about what does the literal type means here? I found

Explicitly invoking `int` destructor - why is a type alias required? [duplicate]

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-05 06:40:23
This question already has an answer here: Pseudo-destructor call does not destroy an object 1 answer The following program... int main() { int{1}.~int(); } does not compile on (see conformance viewer ) : clang++ trunk, with -std=c++1z g++ trunk, with -std=c++1z CL 19 2017 Introducing a type alias for int ... int main() { using X = int; int{1}.~X(); } ...makes the program valid on all previously mentioned compilers, without warnings (see conformance viewer ) . Why is a type alias required when invoking int 's destructor? Is this because int is not a valid grammar element for a destruction

Template template partial specialization only working with -std=c++1z with g++

纵饮孤独 提交于 2019-12-05 05:44:13
I have found that the following piece of code: #include <iostream> #include <vector> template <typename T> struct X : std::false_type {}; template <template <typename> class Y, typename U> struct X<Y<U>> : std::true_type {}; int main() { if (X<int>()) std::cout << "wrong\n"; if (X<std::vector<double>>()) std::cout << "correct\n"; return 0; } Only prints correct when compiled with g++-7 with -std=c++1z . Other versions of g++ , clang++ or other std flags fail to produce correct. Is this a bug of the current implementation, and this code should not print anything, or is something changed in C+