Forum Replies Created
-
AuthorPosts
-
14. July 2022 at 21:15 in reply to: Lamda expression syntax cheatsheet – C++ version numbering seems odd #60994::
Here is the answer of André Müller, creator of the cheat sheets:
“Yes, it is ordered according to “features supported”, so from simplest to most elaborate since I figured this is what one cares about most when writing / reading / talking about a lambda expression. That C++11 comes up twice and the C++23 part is sandwiched in between these two is due to the fact that in C++11 it was not allowed to omit the parameter list when also supplying specifiers like “mutable” (in C++23 it will be).”
::It is no contradiction, but Andrea’s formulation may mislead.
- It is unspecified how a lambda is implemented.
- Andreas’s observers different sizes of lambdas depending on the ordering of its elements.
=> His statement is an observation about the clang implementation of lambdas. His observation is not applicable to another compiler, compiler version, or compiler used with other flags. The C++ standards specifies nothing about the layout of a lambda.
::As Tobias mentioned, your Visual Studio Intellisense uses a different toolchain or the toolchain differently. You have to check the Visual Studio configuration. My first assumption was that it was a question of optimization or not. Miscrosoft sometimes complains about code compiled in debug mode, which it accepts in release mode.
::Honestly, I can not reproduce it and have no idea. Additionally, I studied the various versions of delete.
My only guess it that your overload differs because of the noexcept specifier. When you read here https://en.cppreference.com/w/cpp/language/noexcept_spec noexcept takes with C++17 not part in overload resolution. Meaning, you can not overload on noexcept.
Maybe, it was not specified in C++11/14, and you have, therefore, unspecified behavior.
::Here is the general rule: A user-defined or implicitly generated destructor of a type MyType is noexcept by default. If one of the members or bases of MyType has a destructor without a noexcept guarantee, the destructor of MyType has no noexcept guarantee, too.
Consequently, declare your destructor noexcept if you are not sure that all members have a noexcept destructor.
::The following program models in a simplified way RAII similar to all containers of the STL, including std::vector and std::string.
class Vector { int* data; public: Vector(const int size) { data = new int[size]; } // acquire memory ~Vector() { delete[] data; } // release memory void do() {} }; void functionUsingVector() { Vector vector(1000000); // lifetime of vector is bound to its scope vector.do(); } // automatic destruction and deallocation of vector and its data
The critical observation is that the destructor of vector would also be called if an exception happens inside the function functionUsingVector.
::- You are right, Account could be any class.
- Program start-up is essentially the time before main is executed. The following things happen perspective:
- C start-up code requires specific prerequisites
- Puts the interrupt vector table at an appropriate location
- Sets the stack pointer
- Static variables are initializes (.bss section)
- Const variables are stored in a separate section (.rodata section)
- C++ start-up code (additionally)
- Execution of static objects (constructor calls)
- iostreams initialized (cin, cout, cerr, and clog)
- C start-up code requires specific prerequisites
::The first question you have to answer is: “What semantic does f1 and f2 have?”
I already answered your question. A const lvalue reference is an in parameter and a non-const rvalue reference is an in and move from parameter.
Regarding performance, both versions should be equivalent. Here is my simple rule of thumb for a parameter p:
- The sizeof(p) <= 3 sizeof(int): copy
- Otherwise: const lvalue reference
::void f1(const MyClass& myClass) { // in parameter // ... } void f2(MyClass&& myClass) { // in and move from parameter // ... } ... MyClass myClass; f1(myClass); f2(std::move(myClass)); f1(myClass); // myClass has valid but unspecified state
- f1 uses an in parameter that you cannot change
- myClass is still usable by the caller
- f2 uses an in and move from parameter
- you enforce the caller to transfer the ownership of myClass into the function f2
- the lifetime of myClass is bound to the lifetime of f2
- myClass must after the call f2(std::move(myClass)) initialized
12. June 2022 at 08:14 in reply to: clang-tidy warnings that can appear when using std::move() #10937::I made a complete program out of it:
#include <iostream> #include <string> std::string getString() { const std::string s; return std::move(s); } int getInt() { int x{10}; return std::move(x); } void f(const std::string &s){} int main() { std::string s = getString(); std::cout << getInt() << '\n'; f(std::move(s)); }
clang-tidy on Compiler Explorer gives the expected messages: https://godbolt.org/z/a575xebMa
-
AuthorPosts