c++17

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

倖福魔咒の 提交于 2019-12-04 03:33:09
问题 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

inline static member variable

孤人 提交于 2019-12-04 03:11:20
struct sa { struct sb { int a = 123;}; inline static sb b; }; The above code generates an error: main.cpp:25:20: error: default member initializer for ‘sa::sb::a’ required before the end of its enclosing class inline static sb b; ^ main.cpp:24:21: note: defined here struct sb { int a = 123;}; ^~~~~~ Removing the inline keyword or the default member initializer works. But just from the output, I don't understand why this usage is wrong. I think this code is correct and should be accepted; gcc and clang are erring on the side of caution in order to avoid the defect of Core Issue 1397 . That

Why do boost::filesystem::path and std::filesystem::path lack operator+?

家住魔仙堡 提交于 2019-12-04 02:50:53
问题 Consider the following assertions about path decomposition, where each local variable e.g. stem has the obvious initialization e.g. auto stem = path.stem() — assert(root_path == root_name / root_directory); assert(path == root_name / root_directory / relative_path); assert(path == root_path / relative_path); assert(path == parent_path / filename); assert(filename == stem + extension); This all works, except for the last line — because fs::path does not define an operator+ . It has operator+=

Clang and the binary fold expressions — The curse of the empty parameter pack

你。 提交于 2019-12-04 02:16:21
Specifically Clang 3.6.0, the one currently hosted by Coliru. All these snippets are called from : int main() { foo(); std::cout << "\n----\n"; foo(1, 2, 3); } The following code : template <class... Args> void foo(Args... args) { std::cout << ... << args; } Triggers the following compilation error : main.cpp:7:17: error: expected ';' after expression std::cout << ... << args; ^ ; main.cpp:7:15: error: expected expression std::cout << ... << args; ^ So I tried putting parentheses around the expression : (std::cout << ... << args); It works, but triggers a warning : main.cpp:7:6: warning:

Avoid calling move constructor

喜夏-厌秋 提交于 2019-12-04 01:53:46
I have following example #include <cstdint> class FooC { public: FooC(uint16_t iPort, uint16_t iPin) : PORT(iPort) , PIN(iPin) { }; ~FooC() = default; FooC() = delete; FooC(const FooC&) = delete; FooC(FooC&&) = delete; private: const uint16_t PORT; const uint16_t PIN; }; int main() { FooC array[2] = { FooC(1,2), FooC(3,4) }; } and I don't want to call the default, move and copy constructor. Due to that I deleted the functions. Unfortunately this results in following error (compiled with C++11) : In function 'int main()': :28:5: error: use of deleted function 'FooC::FooC(FooC&&)' }; ^ :16:4:

Is there a way to reset a std::variant from a known alternative?

☆樱花仙子☆ 提交于 2019-12-04 01:35:17
I'm in the process of updating a codebase that is currently using a custom equivalent of std::variant to C++17 . In certain parts of the code, the variant is being reset from a known alternative, so the class provides a method that asserts that index() is at a current value, but still directly invokes the proper destructor unconditionally. This is used in some tight inner loops, and has (measured) non-trivial performance impact. That's because it allows the compiler to eliminate the entire destruction when the alternative in question is a trivially destructible type. At face value, it seems to

Associativity of fold-expressions

℡╲_俬逩灬. 提交于 2019-12-04 01:30:20
N4191 proposed fold-expressions to C++. The definition there was that (args + ...) is a left-fold (i.e. (((a0 + a1) + a2) + ...) , and that (... + args) is a right-fold (i.e. (... + (a8 + (a9 + a10))) . However, the revised paper N4295 reversed the definitions of left and right unary folds. Question : what is the rationale? It seems more intuitive (at least when you are used to left-to-right alphabets) to evaluate (args + ...) from left-to-right. From the comment by @cpplearner, here's some archeology from std-discussion On Wed, Feb 4, 2015 at 1:30 AM, @T.C. wrote : In N4295, which was

Union of layout-compatible types

佐手、 提交于 2019-12-04 01:27:44
Look at this code: struct A { short s; int i; }; struct B { short s; int i; }; union U { A a; B b; }; int fn() { U u; u.a.i = 1; return u.b.i; } Is it guaranteed that fn() returns 1 ? Note: this is a follow-up question to this . NathanOliver- Reinstate Monica Yes, this is defined behavior. First lets see what the standard has to say about A and B . [class.prop]/3 has A class S is a standard-layout class if it: has no non-static data members of type non-standard-layout class (or array of such types) or reference, has no virtual functions and no virtual base classes, has the same access control

Why is the const&& overload of as_const deleted?

人走茶凉 提交于 2019-12-04 00:06:32
On a blog on the progress of C++17 I read the following: P0007 proposes a helper function template as_const , which simply takes a reference and returns it as a reference to const . template <typename T> std::add_const_t<T>& as_const(T& t) { return t } template <typename T> void as_const(T const&&) = delete; Why is the const&& overload deleted? Consider what would happen if you didn't have that overload, and try to pass in a const rvalue: template <typename T> const T &as_const(T &t) { return t; } struct S { }; const S f() { return S{}; } int main() { // auto & ref = as_const(S()); //

Constructor called on return statement

橙三吉。 提交于 2019-12-03 23:59:28
Consider the following example: class X { public: X() = default; X(const X&) = default; X(X&&) = delete; }; X foo() { X result; return result; } int main() { foo(); } Clang and GCC disagree on whether this program is valid. GCC tries to call the move constructor when initializing the temporary during the call to foo() , which has been deleted leading to a compilation error. Clang handles this just fine, even with -fno-elide-constructors . Can anyone explain why GCC is allowed to call the move constructor in this case? Isn't result an lvalue? From [class.copy.elision] : In the following copy