Calmness and order, general peace of mind are the desired states of every person. Our life basically goes on a swing - from negative emotions to euphoria, and back.

How to find and maintain a point of balance so that the world is perceived positively and calmly, nothing irritates or frightens, and the present moment brings inspiration and joy? And is it possible to find lasting peace of mind? Yes, it's possible! Moreover, with peace comes true freedom and simple happiness to live.

This simple rules, and they work religiously. You just need to stop thinking about HOW to change and start APPLYING them.

1. Stop asking, “Why did this happen to me?” Ask yourself another question: “What great happened? What good can this do for me? There is goodness for sure, you just need to see it. Any problem can turn into a real gift from above if you consider it as an opportunity, and not as punishment or injustice.

2. Cultivate gratitude. Every evening, take stock of what you can say “thank you” for during the day. If you lose peace of mind, remember the good things you have and what you can be grateful for in life.

3. Load your body physical exercise. Remember that the brain most actively produces “happiness hormones” (endorphins and enkephalins) during physical training. Therefore, if you are overcome by problems, anxiety, insomnia, go outside and walk for several hours. A quick step or run will distract you from sad thoughts, saturate your brain with oxygen and raise the level of positive hormones.

4. Develop a “cheerful posture” and think of a happy pose for yourself. The body has a wonderful way of helping when you need to restore peace of mind. It will “remember” the feeling of joy if you simply straighten your back, straighten your shoulders, stretch happily and smile. Consciously hold yourself in this position for a while, and you will see that the thoughts in your head become calmer, more confident and happier.

5. Return yourself to the “here and now” state. A simple exercise can help you get rid of anxiety: look around, focus on what you see. Start mentally “sounding out” the picture by inserting as many words as “now” and “here” as possible. For example: “I’m walking down the street now, the sun is shining here. Now I see a man, he is carrying yellow flowers...", etc. Life consists only of “now” moments, don’t forget about it.

6. Don't exaggerate your problems. After all, even if you bring a fly close to your eyes, it will take on the size of an elephant! If some experience seems insurmountable to you, think as if ten years have already passed... How many problems have you had before - you have solved them all. Therefore, this trouble will pass, don’t dive into it headlong!

7. Laugh more. Try to find something funny about the current state of affairs. If it doesn’t work out, then just find a reason to laugh sincerely. Watch a funny movie, remember a funny incident. The power of laughter is simply amazing! Peace of mind often returns after a good dose of humor.

8. Forgive more. Resentments are like heavy, foul-smelling stones that you carry around with you everywhere. What peace of mind can one have with such a load? So don't hold a grudge. People are just people, they cannot be perfect and always bring only goodness. So forgive the offenders and forgive yourself.

10. Communicate more. Any pain hidden inside multiplies and brings new sad fruits. Therefore, share your experiences, discuss them with loved ones, and seek their support. Don't forget that man is not meant to be alone. Peace of mind can only be found in close relationships - friendly, loving, family.

11. Pray and meditate. Don't let bad, angry thoughts control you and cause panic, pain and irritation. Change them to short prayers - an appeal to God or to meditation - a state of no-thinking. Stop the uncontrollable flow of self-talk. This is the basis of a good and stable state of mind.

When it seems that the next level has been completed, the Shadows will certainly crawl out and check whether balance and presence of mind are maintained during their dances.

The reaction to the Shadow swings the pendulum of the ego and reveals the ruthless truth: the balance is tense, like the caution of a tightrope walker and is about to threaten to overthrow the brave man into the abyss of the past.

True balance is the absence of obsessive observation: the search for something wrong going on here.

“Everything is as usual,” says the inner contemplator, even if there is a plague or threats around, “it’s just that these people are wounded and need to understand their path.”

But if there are other reactions, then the path has not been completed and the completion of the stage is still ahead.

- Why do I do this? – You are only at the beginning of your journey through the level.
– I am ready to fight to the death! – You have gone one quarter of the way.
– I like this adventure! – half the way has already been passed.
“Come to me, I will save you,” you have passed three quarters of the way.
– How grateful I am to you for being exactly like you! – 2/10 of the way is left until the end of the level.
- Traveler, where are you heading and what do you want to achieve with your aggression? – You have passed this level and are taking the exam of the threatening Shadow.

There is a lot of love and a lot of artistry in the Shadow. Like a good teacher, she perfectly plays Tyrant, Victim and Rescuer to test your balance. After all, in the language of gamers: BALANCE IS THE GOD LEVEL.

©Mark Ifraimov

********

RULES OF CALM

Be willing to let go.

People who fool you, manipulate, blame, complain, are unhappy, drive you crazy, deprive you of emotional peace.

Be equal.

That equality in which everyone is responsible for their own life, and does not expect someone to make them happy or tell them how to live.

Be vigilant.

Don't give in to complaints and manipulation. Relationships are about being present in the life of another, not about saving them. Not to be confused with a direct request for help. They ask - help as much as possible for you.

Be prepared to move away.

Don't get drawn into squabbles and accusations. Don't make excuses. If you are wrong, apologize. That's enough. If you have caused great damage to a person’s feelings, ask what can be done to make amends? If there is no response, be prepared to walk away. This is no longer about your guilt, but about his accusations.

Be firm.

“You are being praised - don’t be happy. They scold you - don’t be upset” (c). You can't win or lose all the time. You can’t even divide everything into losing and winning. Find what you learned and what new things you discovered in yourself thanks to this event. Move forward on your own path, with a firm step.

Be passing.

Walk past other people's conflicts, gossip, categoricalness, judgment, anger, revenge, whining, labels, envy. Don’t get involved in all this, don’t support, don’t waste your time... Move on...

Be prepared to break up.

We continue to get acquainted with the language innovations of the C++17 standard. In this article we will look at what I would call the continuation of the ennoblement of language. Those. We will not see any completely new, from a functional point of view, things here - rather, bringing the old functionality to a more acceptable state. Here we will look at what has changed with the order of execution of subexpressions, what new guarantees have appeared regarding the exclusion of unnecessary copying, and also what new things have been added to lambdas.

Putting things in order

Many C++ programmers have encountered "interesting" problems that present some controversial code and ask, "What will be output?" One common example of such code is the following example:

Int i = 0; i = i++ + i++;

This kind of “smart” code can be found both online and in interviews. The purpose of such questions is to find out how familiar the answerer is with the peculiarities of the order of execution of expressions in C++.

At least this is the declared goal. True, I believe that in most cases the person asking such questions simply wants to stroke his pride. Knowing what such code will output is completely unnecessary, because such code simply cannot be written. And since you can’t write, then why ask the applicant about this? Such questions are appropriate for “smoking rooms” where familiar programmers discuss edge cases; they are not appropriate for interviews. I recommend reading Raymond Chen’s thoughts on this topic: “Do people write insane code with multiple overlapping side effects with a straight face?”

But this is a pathological case that is visible to the naked eye, and, as I already mentioned, a normal programmer would never write like this. But there are also less obvious cases that even experienced programmers can write. Let's look at this piece of code:

Void f2() ( std::string s = "but I have heard it works even if you don"t believe in it"; s.replace(0, 4, "") .replace(s.find("even" ), 4, "only") .replace(s.find(" don"t"), 6, ""); assert(s == "I have heard it works only if you believe in it"); )

This code is presented in last book Stroustrup “The C++ Programming Language 4th edition”, in section 36.3.6, and at first glance it looks quite suitable and correct. But this is only at first glance; in fact, there is no guarantee that the above code will generate the expected string, and, accordingly, the assert will not work.

As we can see, even the creator of C++ made a mistake in such a small piece of code. What does this mean? First of all, there is no need to cram a bunch of code into one expression, in which a lot of different things happen. The first version of this code, which is presented on the same page of the book, is much simpler and better:

Void f() ( std::string s = "but I have heard it works even if you don"t believe in it"; s.replace(0, 4, ""); s.replace(s.find(" even"), 4, "only"); s.replace(s.find(" don"t"), 6, ""); assert(s == "I have heard it works only if you believe in it" ; )

This option is not only correct from the point of view of the flow of the program, it is also easier to read. But this is not the only conclusion we have to draw, there is another one that the authors of proposal P0145R3 have already made for us: there is something wrong with the order of execution of subexpressions of expressions in C++.

Old order

Before we move on to the proposal itself and the changes that its adoption led to, I suggest we recall the current rules. This will help refresh your memory (and help someone find out) why the 2 examples given earlier are bad C++ code (purely from the point of view of language, not aesthetics). So, unlike many other programming languages, in C++ the order of execution of subexpressions in expressions is not determined by the standard and is left to the compiler. Of course, there is still a certain order, but I will not describe all the details here, because... there are quite a lot of them. It is important to understand that, as a rule, 2 subexpressions of one large expression are executed independently of each other in uncertain order (the big exception to this rule is the comma "," operator).

For example, let's take our first example: i = i++ + i++; . There are 4 small subexpressions in a large expression: i , i++ , i++ and i++ + i++ . What does the C++14 standard guarantee? It guarantees (expr.ass) that both expressions i++ will be evaluated before their sum is evaluated, and also that expression i will be evaluated before the result of the sum is assigned to it. I also remind you that the i++ expression returns the old value of i and then increases i by one (increments it). This, in turn, means that the expression is considered evaluated when the old value of i is obtained.

This means that the compiler can choose several ways to evaluate the full expression: it is not limited in when the effect of ++ should be applied to i . As a result we can get different meanings in i , which, of course, is no good, because the program must produce predictable results that are not subject to the whims of the compiler. For example, the order could be:

    We calculate the first i, it is equal to 0.

    We calculate the second i, it is equal to 0.

    We write down the result of the second increment, we get i == 1 .

    We write down the result of the first increment, we get i == 2.

    We calculate i to the left of the equal sign.

    We calculate the sum: 0 + 0 == 0.

    We write the result of the sum in i.

    We return the result of the complete expression, i.e. i, which is equal to 0.

The above steps can be performed in any order that does not violate the guarantees provided by the standard, and the result will be different answers.

By the way, you can consider a simpler option: i = ++i + i++; . Here you can immediately see that the result will be different depending on what is calculated first ++i or i++ , because at the first expression side effects(incrementing i by one) occurs before it is calculated.

Although the second option is more visual, both of them give the so-called output undefined behavior(NP, English undefined behavior). All seasoned C++ programmers are familiar with this term, but it is unlikely that many know all the places in the C++ language where such behavior can occur. It's wide and enough interesting topic, which could be the subject of more than one article, so I won’t dwell on this in more detail. In fact, such a detailed analysis of the expression was not necessary, because according to the standard (intro.execution/p15) our expression is NP already because in one expression there are two subexpressions that modify the same scalar object, and the order of changes is not defined. Why then did I present this analysis? I tried to show why NP manifests itself based on the current restrictions on the execution of expressions, i.e. the goal was to show that with the current rules the standard has no choice but to throw up its hands.

Now let's move on to our second example and figure out what's wrong with it. To make it easier to understand, I will shorten this example to this expression: s.replace(s.find("even"), 4, "only"). What do we have here? There is an object s , there is a call to the member function std::string::replace , another function std::string::find , as well as arguments to these functions. What guarantees does the standard give us? The standard guarantees that a function's arguments will be evaluated before the function is called. It also ensures that the object on which the function is executed must be evaluated before the function on it is called. All this is clear and logical. True, we have no other guarantees: there is no guarantee that s will be calculated before the arguments of the replace function are calculated, and there are also no guarantees regarding the order in which these same arguments are calculated. Therefore, we can get the following calculation order: s.find("even") , "only" , 4 , s , s.replace(...) . Or any other that does not violate the previously stated guarantees of the standard.

From the above text, you need to highlight 2 main points: 1) the expressions to the left and right of the point can be evaluated in any order, 2) the function arguments can be evaluated in any order. Based on this, it should now be clear why the code in Stroustrup's book is incorrect. In the expression:

S.replace(0, 4, "") .replace(s.find("even"), 4, "only") .replace(s.find(" don"t"), 6, "");

Both calls to find may end before the previous (in-code) replace calls are executed. And maybe even after. The first one may be before, and the second one later - it is not known, because... the order is not defined. As a result, this code produces unpredictable results, although it is not NP. However, as I already said, a competent programmer would not write such code, and the fact that it is in Stroustrup’s book does not mean that he would write it like that - he simply gave an example of a chain of calls.

In addition, the chain of calls may not be so obvious. For example, here's the code:

Std::cout<< first << second;

This is also a chain of calls, which can be like this:

Std::cout.operator<<(first).operator<<(second);

or like this:

Operator<<(operator<<(std::cout, first), second);

The difference is not fundamental. If suddenly the expressions first and second somehow refer to the same object, and one of these expressions modifies this object, then there is a high chance that the output will be unstable code or NP.

Another interesting example from the above sentence:

Std::map dictionary dictionary = dictionary.size();

Yes, the code looks meaningless, but what will it produce as a result? Even meaningless code should produce predictable results. Unfortunately, C++ of 2014 just shrugs its shoulders - I don’t know, they say.

Functions and Operators

When we looked at the call chain, we touched on another interesting point: what does the std::cout call actually do?<< first << second; . Как мы уже видели, в зависимости от того, чем являются first и second , мы можем получить либо цепочку вызовов функций-членов, либо же вложенные вызовы свободных функций. Но ведь в изначальном варианте записи у нас есть три выражения и 2 оператора << , у нас нет вообще никаких функций!

It is unlikely that this code caused problems for C++ programmers: we all learn about operator overloading sooner or later and take it all for granted, but there is one nuance to this overloading. To show this nuance, let's write the following function template:

Template << "first\n", value++) && (cout << "second\n", value++); }

Yes, the template is not the most useful and remarkable, but, as we will now see, it is very indicative. Let's call the cleverFun function with an int argument, which will instantiate a function like this:

Bool cleverFun(int& value) ( ​​return (cout<< "first\n", value++) && (cout << "second\n", value++); }

When this function is called, the output is guaranteed to be:

if the first value++ returns 0 , otherwise it will be like this:

First second

And no other, which is obvious: there is a strict guarantee for the && operator short circuit(KZ, English short-circuit) and performing the left part to the right. On the other hand, if we create a certain type Int for which we override both the postfix operator++ and operator&& , and then instantiate our template with it, we will get the following function:

Int cleverFun(Int& value) ( ​​return (cout<< "first\n", value.operator++(0)) .operator&&((cout << "second\n", value.operator++(0))); }

I did not reveal what the cout call turns into, so as not to clutter the already not very easy to read code even more. Based on what we've discussed so far, it shouldn't surprise you that the output of this code will be different from what you'd get for a regular int . Here you can also get 2 options, but they will be different:

First second

Second first

Obviously, we cannot get the option with one first due to the fact that the short circuit for overridden operators does not work. If you look closely at this example, you should understand why: in order to execute an overridden operator&&, the argument must be evaluated for it (i.e., goodbye KB), and besides, KB only works when the expression on the left is a bool , which is the case with the overridden there cannot be an operator. Thus, there can be no illusions about the short circuit - it does not exist and will not exist for overridden operators.

Well, there can’t be a short circuit, so we can’t get the first output option (only first ), but even the option with two output lines may or may not be different! Just think about it: we have the same code inside a function template, which, for some template arguments, is executed according to one rule, and for others according to completely different ones.

This all happens because in C++14, the guarantees for operators and their operands differ depending on what the operands are. According to the standard, for integral types all operator guarantees work as they are described for them in the standard, but for overridden operators the rules that govern calling functions already work. Those. for overridden operators, the expression is “rewritten” by the compiler into the function call chain, and after that the rules from the standard that are defined for such a chain are applied. Any operator guarantees from the standard do not apply to overridden operators..

Everything previously described paints a very bleak picture: there is too much chaos in C++ when it comes to evaluating expressions. It’s no wonder that people are tired of putting up with such things, and the eternal statements that all this is needed for some mythical optimization and should not be changed are no longer considered a sufficient justification. Common sense prevailed, and C++17 received few changes in terms of cleaning up this mess. And what kind of changes are we now going to look at?

New order

The first change brought by C++17 is the ordering execution postfix operators, assignment operators, and bitwise shift operators. Now all postfix operators, as well as bitwise shift operators, are executed from left to right, while assignment operators are executed from right to left. By "executed", in this context, I mean that the expression is evaluated (that is, its result is returned), and all side effects associated with it are committed.

To explain how the expressions are now ordered, let's take an example from a sentence (in the example below, the expression a is executed first, then b):

A.b a->b a->*b a(b1, b2, b3) b @= a a[b] a<< b a >> b

Where @ is any valid operator in this context (for example + ). Thus, based on the new rules, the example given in Stroustrup's book on C++11 finally becomes correct in C++17 and will always produce the correct and expected result. As you can see, the new rules do not affect the order in which function arguments are executed relative to each other: they can still be executed in any order, but their execution cannot interleave. In other words, they are ordered relative to each other, but the order is not regulated.

Now let's look at some "interesting" examples where in C++14 we had NP, but in C++17 it disappeared. I give these examples solely for my own consumption, I implore you not to torment people with them during interviews.

I = i++; f(++i, ++i) f(i++, i++) array = i++ i<< i++ cout << i++ << i++

But these examples remain NP in the new standard:

I = i++ + i++ i = ++i * i++

Because no rules were added regulating the order in which subexpressions of arithmetic operators are executed. But the fact is that The disappearance of NP from these examples does not mean at all that it is time to saturate your code with similar ones - no. Each of these examples requires care and proof that it is not NP. Those. any programmer who sees such code will be forced to stop, remember (or look into the standard) and make sure that he sees the correct code in front of him. The code should not be “smart”, the code should be understandable. Moreover, such a combination of expressions gives little, in fact.

By the way, the attentive reader probably noticed the line cout<< i++ << i++ в вышеприведённых примерах, и если он не знает обо всех правилах и поверил автору, то он наверняка воспользовался такой логикой: пример переписывается как

Cout.operator<<(i++).operator<<(i++)

after which the new rules for . , so it's not in the code NP. Such reasoning seems logical, but is not entirely correct. In fact, everything is simpler: the example is actually “rewritten” by the compiler to the one I gave, but the execution order is built before the rewriting! Those. according to the new rules, overloaded operators obey the execution rules for built-in operators, at least in terms of the order in which subexpressions are evaluated. Therefore, based on the fact that the left operand of the operator<< вычисляется до правого у нас и нет NP in the code.

It turns out that we no longer have a discrepancy in the order in which expressions for built-in and overloaded operators will be executed, and our example from the last section:

Template bool cleverFun(T& value) ( ​​return (cout<< "first\n", value++) && (cout << "second\n", value++); }

for any type it will always print first and then second . The reverse order of output is now excluded by the standard. This is, of course, a very important innovation, which allows you to reason about the code that is written, and not what will be generated from it. It is interesting to note that this innovation created a difference between explicitly and implicitly calling an overloaded operator. Let's look at an example:

#include using namespace std; class SomeClass ( friend int operator<<(const SomeClass& obj, int&); public: SomeClass(int var): m_Var{var} { } private: int m_Var; }; int operator<<(const SomeClass& obj, int& shift) { return obj.m_Var << shift; } int main() { int i = 0; int result = SomeClass{i = 1} << (i = 2); cout << "First result: " << result << "\n"; result = operator<<(SomeClass{i = 1}, i = 2); cout << "Second result: " << result << "\n"; };

The first result is guaranteed to be 4, while the second can be either 2 or 4. This example shows well the difference between explicitly and implicitly calling an overloaded operator in C++17.

Obviously, with the introduction of the new order, many different complex expressions appeared that gave NPs in previous standards are now acceptable, but this does not mean that they should begin to appear en masse in the code. This shouldn't happen just because they are complex, and anything that is difficult to understand should be avoided. But the new rules not only give us the ability to call functions like f(i++, i++) without fear of getting a broken program. The new rules give C++ code more rigor and order, thanks to which, among other things, we can now write reliable code with a chain of calls (explicit or implicit, it doesn’t matter).

While I did say a bit about the code in Stroustrup's book, I'm not an opponent of call chaining, and if we look at modern code written using imperative languages, we can see that it contains more and more chaining (for example, LINQ and Task+ContinueWith from C#, or Lodash/underscore and Promise+then from JS). C++ is also moving in this direction, and soon we will be able to see analogues of the above examples in the form of Range-v3 and future+then in future C++ standards. But even before new standards are released, we can use various libraries whose interface encourages the use of call chains.

Overall, in my opinion, the change in the rules for the order in which expressions are evaluated is one of the most important innovations in C++17, which few will notice, because everything (or almost everything) will simply work the way it should work according to common sense. And there is more and more common sense in the C++ standard every day.

Minimizing copying

One of the first steps in learning C++ is learning the copy constructor. After all, with its help you can easily determine what is copied and when. Those. we write our own class, add a copy constructor there, in which we write the output via cout , and enjoy the output, based on the result of which we find out how many copies we are creating.

With the advent of move semantics, the situation has become somewhat more complicated, so to complete the picture, now you also need to create a move constructor. But for this section it doesn’t matter, because... everything written below is true for both copying and moving.

For example, let's write this code:

#include using namespace std; class SomeClass ( public: SomeClass() = default; SomeClass(const SomeClass&) ( cout<< "Copy ctor called.\n"; } }; SomeClass meReturn() { return SomeClass{}; } int main() { auto some = meReturn(); };

How many times will the phrase “Copy ctor called.” appear on the screen if you compile this code on a compiler that implements C++14 and run the program? Zero, one, or maybe two times? Correct answer: unknown.

Those for whom the answer came as a surprise deserve an explanation, to which we now turn. So, first, let's unpack the standard and consider what the maximum number of copies is here Maybe be created. The largest number of possible copies here is 2: the first copy is created when the return statement is executed, and the second copy is created when the some object is constructed. But if you run this code on a more or less modern compiler (without additional switches!), you are unlikely to see double output; the more likely outcome is either one line, or there will be no output at all. Now let’s slightly modify the code of our function, this will be the second option:

SomeClass meReturn() ( SomeClass some(); return some; )

If we run this code on popular compilers, the output may or may not change (it changes on MSVC 2017, in debug mode). Finally, we will change the function code a little more, only this time the output is guaranteed to change (relative to the first option and taking into account the current state of things with compilers):

SomeClass meReturn() ( SomeClass some(); if (false) return SomeClass(); return some; )

So, the function is essentially the same in all variants, but the behavior is different - what's going on here? Let's start from the beginning. According to the C++ standard, in some cases the compiler may not copy an object; this situation is called copy skip(PC, English copy elision). A complete list (rather short) of signs that can be used to determine whether skipping copying is allowed is described in class.copy/p31. We are interested in two similar, but still different situations.

In the original example, our function returns a temporary nameless object. In such a situation, the compiler has the right to skip both copies and simply create the object directly in some . This situation is popularly called return value optimization(OVZ, English return value optimization). If we look at gcc/clang/MSVC, we see that for such a function they get rid of both copies and hence the output will be empty.

This kind of optimization is allowed not only for return , but also for other places where initialization occurs with a temporary, nameless object. So, if you have a void meAccept(SomeClass) function that is called meAccept(SomeClass()) , then the compiler has the rights to omit the redundant copying.

Now let's move on to the second option, where we created named object on the stack. The output for gcc/clang did not change, but for MSVC (in debug mode) one line appeared in the output, it is obvious that in this case MSVC got rid of only the second copy. Based on the above, it becomes clear that the compiler also uses PC, but here it happens according to a slightly different criterion: it has the right to get rid of copying named object on the stack that is returned from the function. This type of optimization is popularly called named return value optimization(OIVZ, English named return value optimization).

This kind of optimization is more difficult for the compiler to perform, which is what we see in the third option, where we added an absolutely useless if , which forced all three major compilers to give up and make a copy. Thus, OIVZ is a more fragile optimization than simple OIV, and, as a rule, it is disabled when there are several different returns in the code. This is one of the reasons why there should be only one return in a function (I can’t say that the argument is very convincing).

An interesting fact is that the above optimization is applied in compilers even when we compile with optimization disabled (-O0 , /Od ). Moreover, only gcc and clang can be forced to create all copies. To do this, you need to use the -fno-elide-constructors switch, and under no circumstances will MSVC create two copies, and there are no [public] switches to disable this behavior.

There is another point that should be mentioned. Although in C++14 the compiler can remove both copies, thereby not executing the copy constructor even once, it should throw a compilation error if there is no such constructor. Those. if instead of the existing copy constructor we write this: SomeClass(const SomeClass&) = delete, then the program will not be built even when compilers can quite legally get rid of copying - there must still be a constructor.

And finally, the third point: movement. If the compiler can omit copying, it can omit moving. Those. in this regard they are absolutely equivalent. In this regard, by the way, there is an interesting situation. Many programmers (I draw a conclusion about many based on the code that I saw on the Internet) do not quite understand the semantics of moving and write code similar to this: return std::move(someObject) . The code looks absolutely harmless and works as expected by the person who wrote it, but this is the code guaranteed disables OIVZ. What do you think is better: executing one cheap move constructor, or not executing anything at all?

New reality

Now it's time to look at what has changed in C++17 regarding the PC. All of the changes that we will discuss in this section are part of can be found in the original P0135R1 proposal. If you look at this document, you will see that it describes numerous changes to the standard in terms of the category of expressions (mostly prvalue), as well as various edits clarifying where to explicitly perform direct(direct-) and copying(copy-) initialization. Of this entire set, we are only interested in one change, which is described in stmt.return/p2.

So, according to the above innovation, returning from a function a temporary unnamed object (prvalue) of the same type (i.e. no conversion required) as the function's return type performs a copy initialization of the result (which, according to dcl.init/p(17.6. 1), allows you to skip copying). What is written in the sentence above is, in essence, the same HIA, only this time mandatory. Those. if the compiler is C++14 could get rid of copy/move in this case, then now it obliged do it. What does this give us, since we have already seen that the compiler itself does an excellent job? And this gives us the following, having the following code:

SomeClass meReturn() ( return SomeClass(); )

We can have no copy and move constructors at all, and it will still compile. It is important to note that only the case has changed when another object is created from a temporary nameless object, but if we return a named object (OIVZ), then even if the compiler can skip copying, the presence of an appropriate constructor is mandatory.

There is one more point, which is already related to the passing of arguments, and not the return value. If we have this code:

Void meAccept([] SomeClass s) ( )

Then, when calling the meAccept(SomeClass()) function, there will also be no copying and this again is no longer an optimization, but a requirement of the standard. This is due to changes in the definition of prvalue (basic.lval) and what this change entails. Let's take a look at this line: meAccept(SomeClass()) . In old prvalue terms, SomeClass() is a temporary object that is then copied into the function parameter. But the new definition of prvalue is that it is no longer object, But expression, whose evaluation is the initialization of the object. What does this mean for us? This means that in the expression we are considering, SomeClass() is not a temporary object, but an expression for initializing a function parameter. Here, the previously mentioned rule described in dcl.init/p(17.6.1) is enabled, and no copying occurs - initialization is performed directly.

At first glance, this is a rather insignificant innovation, because the same thing happened before, it’s just that compilers were not obliged to do this. However, this innovation changed the very essence of the prvalue concept, so it should not be considered insignificant. And from a purely practical point of view, you need to know about this change, because when learning a language, we learn it empirically, and in this process, experiments with copy/move constructors are very common. So, starting with C++17, you cannot in any way force the compiler to make a copy in the previously described examples. No flags will help if the program is compiled for C++17, and the compiler actually supports it. As for everyday code, this innovation allows you to create factory functions that return objects that do not have copy/move constructors. How necessary is this? Time will show.

Lambdas

The committee continues to show lambdas its love, adding something new to them in each new edition of the standard. 2017 was no exception, and lambdas received their share of innovations. Although I continue to wait for a short syntax (like C#'s x => x ) and consider the innovations of this standard to be insignificant, I still cannot ignore them.

Capturing this

So, the first innovation. You can now pass a copy of an object to the capture list using the this pointer. Before C++17, if we wanted to pass a copy of the current object to a lambda, we were forced to write something like this:

#include using namespace std; class SomeClass ( public: SomeClass(size_t value): m_Value(value) ( ​​) void someMethod() ( auto lambda = [_this = *this] ( for(size_t i = 0; i< _this.m_Value; ++i) cout << "This is lambda!!!\n"; }; lambda(); } private: size_t m_Value; }; int main() { SomeClass some{3}; some.someMethod(); };

The main disadvantage of this approach is the need to explicitly specify the name of the object into which we copied *this every time we access it. C++17 corrects this shortcoming, allowing you to write like this:

Auto lambda = [*this] ( for(size_t i = 0; i< m_Value; ++i) cout << "This is lambda!!!\n"; };

Those. access to the members of the object is carried out exactly the same as if we created a lambda with such a capture list, but in this case, not the current object (i.e. the this pointer), but a copy of it is passed to the lambda. I would like to note that I have not had to write such code, so it is difficult for me to evaluate the usefulness of the innovation, but it will obviously make life easier for someone. I can only be happy for them and move on to the next innovation.

Need more consistency!

Another change that has been long overdue is the addition of the ability to use lambdas in constant expressions. Of course, such lambdas must also be constant. For example:

Auto eleven = ( return 11; ); array arr;

As you can see, nothing has changed in the lambda definition, but its call is used in a context where the use of a compile-time constant is mandatory. Because This code compiles successfully, any attentive programmer can draw the following conclusion: the operator() of the class generated from the lambda is a constexpr member and this conclusion is undoubtedly correct. Since C++17, all lambda expressions are constexpr by default, whereas before C++17 they were simply const . But they will be relegated to const if the body of the lambda function does not meet at least one criterion that all constexpr functions are subject to (the criteria are described in dcl.constexpr ). Let's make a minimal change to our code, and the lambda will no longer be constexpr:

Auto eleven = ( int x; return 11; );

With such a lambda, the array creation code will give a compilation error (which is what we actually wanted), but the creation of the lambda itself will not give an error. However, we can tighten the screws and require the lambda to have a body that obeys the above rules:

Auto eleven = () constexpr ( int x; return 11; );

Note that we had to add both the obvious constexpr and () , which does not carry any functional load and only serves the whims of the standard. This way we can create lambda functions that are guaranteed to be usable in a constexpr context.

This change has been a long time coming, and should not come as a surprise to anyone: simple functions can be constexpr , member functions can too, why are lambdas worse? How necessary are constexpr lambdas? This is a more interesting question. I think that constexpr code needs them as much as simple code needs them. There's a constexpr boom in C++ right now, with people competing to see who can go the furthest in moving work from runtime to compile time.

They go as far as writing a JSON parser and even executing regular expressions (for those interested, watch the video from CppCon2017: "constexpr ALL the Things!"). In addition, more and more standard (and not so standard) algorithms are becoming constexpr , which gives rise to the most obvious use of lambdas, because they are simply created for algorithms. Therefore, in my opinion, adding constexpr is a good step forward, which will allow you to write more code that will be executed at compile time.

On the other hand, do we really need to move so much to the compilation stage? Of course, when something can be moved from multiple dynamic execution to single execution at compile time, this is a definite plus. Or not? It depends on the task and the benefits we receive during execution. Let us write a JSON parser that consumes a lot of RAM and increases compilation time (look at least the last 3 minutes of the above-mentioned video), what does this give us? Yes, now we can parse the configuration at compile time and use it in code. But we could have done this before, without using JSON, and it would also have zero runtime load (just a set of flags in the header, for example). This reminds me of a bearded joke:

Two friends meet:

— I heard that you bought a car?

- Yes! And how I used to live! Now I have time to do everything! Yesterday in one day I managed to change the oil, buy new tires, went to the car market to buy fenders, immediately went to a car service center and changed them, and also went to the store for anti-freeze. How could I have done all this without a car?!

People may object to me that JSON is more convenient. So be it. Then let's add a script in Python (or even CMake), which will generate a configuration object from JSON for us. Yes, we'll have to add one more step to building our project, but is that any more difficult than writing C++ code that parses JSON? And no one has canceled the compilation time (and I think this reason is much more significant): if the code takes a long time to compile, then development will turn into hell. Therefore, I see absolutely no point in transferring complex things to constexpr rails. In my opinion, this is an unnecessary complication that can be shown at conferences, but is completely unnecessary in real code. The use of compile-time calculations should be justified, not just because “we can now!”

The last two paragraphs may give the wrong idea about my attitude to this innovation: I'm not against it, I'm just against hammering nails with a microscope, that's all. An example of the latter is clearly visible in the video from CppCon, but the very appearance of constexpr lambdas is certainly good news, because lambdas, functionally, should not differ in any way from ordinary functions - they should have all the same capabilities, and if my memory fails changes, there is only one thing left to add: named template parameters for lambdas. Are we expecting them in C++20?

In any incomprehensible situation, calm down, lie down, hug yourself, go eat some delicious food. Take care of your nerves :)

Leave mistakes to the past.

Appreciate the present.

Smile to the future)

As soon as you let go of the situation that torments you, the situation will immediately let you go.




Don't lose your temper. There is no telling what might happen in your absence.

Go to the tree. Let it teach you peace.

- What is the secret of your calm?

“In complete acceptance of the inevitable,” answered the Master.

Put things in order in your thoughts and you will see the world with different eyes.

Don't forget to cleanse your heart.

What is peace?

No unnecessary thoughts.

And what thoughts are unnecessary?

(Wei De-Han)

Your most important treasure is peace in your soul.

Chamomile is calming.

Control your mood, for if it does not obey, it commands.


You can find peace only by becoming an observer, calmly looking at the fleeting flow of life. Irwin Yalom



Calmness is stronger than emotions.

Silence is louder than a scream.

And no matter what happens to you, don’t take anything to heart. Few things in the world remain important for long.

Erich Maria Remarque "Arc de Triomphe" ---

If you get caught in the rain, you can learn a useful lesson from it. If it starts raining unexpectedly, you don't want to get wet, so you run down the street towards your house. But when you reach home, you notice that you are still wet. If you decide from the very beginning not to speed up your pace, you will get wet, but you will not fuss. The same should be done in other similar circumstances.

Yamamoto Tsunetomo - Hagakure. Samurai Book



Tomorrow will be what it should be

and nothing will happen that should not happen -

don't fuss.

If there is no peace within us, it is useless to look for it outside.

Unburdened with worries -
enjoys life.
He is not happy when he finds it,
when losing he is not sad, because he knows
that fate is not constant.
When we are not bound by things,
Serenity is fully experienced.
If the body does not rest from tension,
it wears out.
If the spirit is always in worries,
he fades.

Chuang Tzu ---

If you throw a stick to a dog, it will look at the stick. And if you throw a stick to a lion, he will, without looking up, look at the thrower. This is a formal phrase that was said during debates in ancient China if the interlocutor began to cling to words and stopped seeing the main thing.

As I breathe in, I calm my body and mind.
As I exhale, I smile.
Being in the present moment, I know that this moment is amazing!

Allow yourself to breathe deeply and don’t force yourself into limits.

Strength belongs to those who believe in their own strength.

Develop the habit of monitoring your mental-emotional state through self-observation. It is good to regularly ask yourself: “Am I calm at this moment?” is a question that is useful to ask yourself regularly. You can also ask: “What is happening inside me at the moment?”

Eckhart Tolle

Freedom is freedom from worry. Once you understand that you cannot influence the results, ignore your desires and fears. Let them come and go. Don't feed them with interest and attention. In reality, things are done to you, not by you.

Nisargadatta Maharaj


The calmer and more balanced a person is, the greater his potential and the greater his success in good and worthy deeds. Equanimity of mind is one of the greatest treasures of wisdom.


The basis of all wisdom is calmness and patience.

Stop your worry and then you will be able to see the magnificent pattern...

When the mind comes to peace, you begin to appreciate the light of the moon and the blow of the wind and understand that there is no need for the bustle of the world.

Find peace in your soul, and thousands around you will be saved.

In fact, you only want peace and love. You came from them, you will return to them and you are them. Papaji


The most beautiful and healthy people are people who are not irritated by anything.


The highest degree of human wisdom is the ability to remain calm despite external thunderstorms.



You are not bound by your experiences, but by the fact that you cling to them.

Don't make hasty decisions. Well weigh all the pros and cons. Almost every person has a heavenly guide, a second self. Think and ask him, is it worth doing what you have planned or not?! Learn to observe, see the invisible, anticipate situations.

When you contemplate mountain forests and streams running over stones, your heart, clouded by worldly dirt, gradually becomes clear. When you read the ancient canons and look at the paintings of ancient masters, the spirit of worldly vulgarity little by little dissipates. Hong Zichen, Taste of Roots.


Wisdom comes with the ability to be calm. Just watch and listen. Nothing more is needed. When you are at peace, when you just watch and listen, it activates the concept-free intelligence within you. Let peace guide your words and deeds.

Eckhart Tolle


We can never achieve peace in the outer world until we achieve it in the inner world.

The essence of balance is not to cling.

The essence of relaxation is not to hold on.

The essence of naturalness is not to make an effort.

One who is not envious and does not wish harm to anyone has achieved balance. For him, the whole world is filled with happiness.

For life to bloom again, seethe and be filled with exciting joy and happiness, you just need to stop... Stop and allow yourself to dissolve in pleasure...

Don't worry about your future, be at peace now and everything will fall into place.

If the water is not clouded, it will settle on its own. If the mirror is not dirty, it will reflect light on its own. The human heart cannot be made pure by one's will. Eliminate that which pollutes it, and its purity will manifest itself. You don't have to look outside yourself for joy. Eliminate what bothers you, and joy will automatically reign in your soul.


Sometimes just leave it alone...

It's always quiet in the center of a hurricane. Be that quiet place in the center, even if there are storms all around.

You are heaven. Everything else is just weather.

Only in calm waters are things reflected undistorted.

Only a calm consciousness is suitable for perceiving the world.

When you don't know what to do, wait a while. Hide. Live the way you live. The sign will appear sooner or later. The main thing is to know that you are waiting and to be ready to face what you are waiting for. Luis Rivera

Don't worry about your future, be at peace now and everything will fall into place.


Calmness deprives your enemies of strength. In calmness there is neither fear nor excessive anger - only reality, cleared of distortions and interference from emotional outbursts. When you are calm, you are truly strong.

Therefore, your opponents will always try with all their might to bring you out of this state - to instill fear, sow doubts, cause anger. The internal state is directly related to breathing. Whatever situation you find yourself in, immediately calm your breathing - your spirit will calm down afterwards.


The most important thing in spiritual life is to keep your heart in peace.

You need to trust life.
We must entrust ourselves to its flow without fear, because life is infinitely wiser than us.
She will still treat you in her own way, sometimes quite harshly,
but eventually you will realize that she was right.

Be at peace now and everything will fall into place.

Your spirit should not be agitated, no evil word should come from your lips; you must remain benevolent, with a heart full of love, containing no secret malice; and even ill-wishers you must embrace with loving thoughts, generous thoughts, deep and boundless, cleansed of all anger and hatred. This, my students, is how you should act.

Only calm water reflects the heavens correctly.

The best indicator of the level of consciousness is the ability to calmly relate to life's difficulties.

They pull the unconscious person down, while the conscious person rises more and more.

Eckhart Tolle.


Sit quietly and you will understand how fussy everyday worries are. Be silent for a while and you will understand how empty everyday speech is. Give up everyday chores, and you will understand how much energy people waste in vain. Chen Jiru.


Calmness helps us find a way out of the most difficult situations.

Have you run out of patience?...Inflate again!)

3 QUIET SECONDS

It is enough to think calmly for three seconds to understand everything.

But where can I get them, these truly three quiet seconds? We are too excited by our own fantasies to stop even for a moment.


Have you ever seen an oak tree in a state of stress, a dolphin in a gloomy mood, a frog suffering from low self-esteem, a cat that cannot relax, or a bird burdened with resentment? Learn from them the ability to come to terms with the present.
Eckhart Tolle

Take your time. Each bud blooms in its own time. Don't force a bud to become a flower. Do not bend the petals. They are gentle; you will hurt them. Wait and they will open on their own. Sri Sri Ravi Shankar

Don't worship the bearded man in the sky or the idol in the book. Worship the inhalation and exhalation, the winter breeze caressing your face, the morning crowd of people on the subway, just the feeling of being alive, never knowing what is coming.Notice God in the eyes of a stranger, Providence in the broken and ordinary. Worship the ground you stand on. Make every day a dance, with tears in your eyes, contemplating the divine in every moment, notice the absolute in everything relative, and let people call you crazy. Let them laugh and make jokes.

Jeff Foster

Supreme power is not the ability to conquer others, but the ability to become one with others.

Sri Chinmoy

Try, at least in a small way, not to bring your mind.
Look at the world - just look.
Don't say "like" or "dislike". Don't say anything.
Don't say words, just watch.
The mind will feel uncomfortable.
The mind would like to say something.
You simply tell your mind:
“Be quiet, let me see, I’ll just watch”...

6 wise tips from Chen Jiru

1. Sit quietly and you will understand how fussy everyday worries are.
2. Be silent for a while and you will understand how empty everyday speech is.
3. Give up everyday chores, and you will understand how much energy people waste in vain.
4. Close your gates and you will understand how burdensome the bonds of acquaintance are.
5. Have few desires, and you will understand why the diseases of the human race are so numerous.
6. Be more humane, and you will understand how soulless ordinary people are.

Free your mind from thoughts.
Let your heart calm down.
Calmly follow the turmoil of the world,
Watch how everything falls into place...

A happy person is very easy to recognize. He seems to radiate an aura of calm and warmth, moves slowly, but manages to get everywhere, speaks calmly, but everyone understands him. The secret of happy people is simple - the absence of tension.

If you are sitting somewhere in the Himalayas and silence surrounds you, it is the silence of the Himalayas, not yours. You must find your own Himalayas within...

Wounds inflicted by thoughts take longer to heal than any other.

JK Rowling, "Harry Potter and the Order of the Phoenix"

Wisdom comes with the ability to be calm.Just watch and listen. Nothing more is needed. When you are at peace, when you just watch and listen, it activates the concept-free intelligence within you. Let peace guide your words and deeds.

Eckhart Tolle "What Silence Says"

The calmer and more balanced a person is, the greater his potential and the greater his success in good and worthy deeds. Equanimity of mind is one of the greatest treasures of wisdom.

James Allen

When you live in harmony with yourself, you are able to get along with others.

Eastern wisdom -

You sit and sit for yourself; you go - and go yourself.
The main thing is not to fuss in vain.

Change your attitude towards the things that bother you, and you will be safe from them. (Marcus Aurelius)

Bring your attention to your solar plexus. Try to imagine that a small ball of sun is lighting up inside you. Allow it to flare up, become bigger and stronger. Let its rays illuminate you. Let the sun saturate your entire body with its rays.

Harmony is evenness in everything. If you want to make a scandal, count to 10 and “launch” the sun.

Calm, just calm :)

Be as interested in what's going on inside you as in what's around you. If everything is in order in the inner world, then everything in the external world will fall into place.

Eckhart Tolle ---

A fool and an ignoramus have five signs:
angry for no reason
they talk unnecessarily
changing for unknown reasons
interfere in something that does not concern them at all,
and they do not know how to distinguish who wishes them good and who wishes them evil.

Indian proverb ---

What goes away, let it go.
Whatever comes, let it come.
You have nothing and never had anything except yourself.

If you could simply maintain inner silence, uncontaminated by memories and expectations, you would be able to discern a beautiful pattern of events. It is your worry that creates chaos.

Nisargadatta Maharaj ---

There is only one path to happiness - this is to stop worrying about those things that are beyond our control.

Epictetus ---

When we lose our sense of self-importance, we become invulnerable.

To be strong, you must be like water. There are no obstacles - it flows; dam - it will stop; If the dam breaks, it will flow again; in a quadrangular vessel it is quadrangular; in the round - she is round. Because she is so compliant, she is needed most and most powerfully.

The world is like a train station, where we are always either waiting or rushing.

When your mind and feelings slow down to the beat of the Heart, you spontaneously come into harmony with the cosmic rhythm. You begin to perceive the world through divine eyes, observing how everything happens on its own and in its own time. Having discovered that everything is already in tune with the law of the Universe, you come to the understanding that you are not different from the world and its Lord. This is Freedom. Muji

We worry too much. We take it too seriously. We need to take things more simply. But wisely. No nerves. The main thing is to think. And don't do anything stupid.

What you can perceive calmly no longer controls you...

Peace cannot be found anywhere for those who have not found it within themselves.

Being angry and irritated is nothing more than punishing yourself for other people's stupidities.

You are the sky. And clouds are something that happens, comes and goes.

Eckhart Tolle

Live with peace. Spring will come and the flowers will bloom on their own.


It is known that the calmer a person looks, the less often other people contradict him and argue with him. And vice versa, if a person defends his point of view with vehemence, he is resisted reasonably and violently.

Take your time. Eat at the hour of eating, and the hour of travel will come- hit the road.

Paulo Coelho "The Alchemist"

Surrender means accepting what is. So you are open to life. Resistance is the internal clamp... . So you are completely closed. Whatever you do in a state of internal resistance (which can also be called negativity), it will cause even more external resistance, and the universe will not be on your side, life will not help you. Light cannot enter through closed shutters. When you give in internally and stop fighting, a new dimension of consciousness opens up. If action is possible... it will be done... supported by the creative mind... with which, in a state of inner openness, you become one. And then circumstances and people begin to help you, become at one with you. Happy coincidences happen. Everything works out in your favor. If action is not possible, you experience the peace and inner peace that comes with giving up the fight.

Eckhart Tolle New Land

"Calm down" message For some reason it always irritates me even more.Another paradox.Usually after such a callno one even thinks about calming down.

Bernard Werber Cassandra's Mirror

He who humbled himself defeated his enemies.

Silouan of Athos

The one who keeps God within himself is calm.


When you argue with a fool, he is most likely doing the same thing.

The true strength of a person is not in impulses, but in unshakable calm.

The highest degree of human wisdom is the ability to adapt to circumstances and remain calm in spite of external storms.

Interfering feelings and thoughts will disappear if you do not pay attention to them. Lama Ole Nydahl

You will never regret what you managed to keep silent about.
--- Eastern wisdom ---

It is worth striving for a state of consciousness in which all events will be perceived neutrally.