📜 ⬆️ ⬇️

Auto - pros and cons

Introduction


Good day, friends! Today we will talk about the auto operator in C ++.
A little background: this operator came to us in C ++ 11 and since then has deeply entered the life of many programmers and various projects. Today I would like to talk about some pros and cons from my point of view.


And what is it eaten with?


So, where is his best, I think, to apply?


1. Lambda


Following the auto with 11 standard language came to us lambda functions . Consider an example:


  // C++98 struct { bool operator()(int a, int b) const { return a < b; } } customLess; std::sort(s.begin(), s.end(), customLess); 

Good old std :: sort with overload on its sorting algorithm. In C ++ 98, for such code, it was required to create a shell through a structure. With the advent of lambda, the situation has changed a lot:


  // C++ std::sort(s.begin(), s.end(), // Lambda begin [](int a, int b) { return a > b; } // End ); 

2. STD Types


We all have ever used std and are using it now. But std types have one big problem ... They are too long.


  int n1 = 3; std::vector<int> v{ 0, 1, 2, 3, 4 }; //  1 std::vector<int>::iterator OldStyle = std::find(v.begin(), v.end(), n1); //  2 auto NewStyle = std::find(v.begin(), v.end(), n1); 

Case one: std :: find returns a type equal to std::vector<int>::iterator , but we ourselves know that very well. In many projects, for example, in the same X-Ray game engine, for such iterations, there were done taypdef, ala:


 typedef std::vector<int> vec_int; typedef vec_int::iterator vec_int_it; 

But I'm not a fan of this code, so it’s easier for me to use auto , as shown in the second case.


3. Range-base-for loops


The long-awaited innovation in C ++ was the RB-For cycles. Well, as an innovation, in C # and C ++ / CLI they already were, but the native still lagged behind ...
When we need to sort through, say, the elements of std :: map, we have to refer to std :: pait. But do not forget about auto! Consider the situation, referring to the source code xray-oxygen :


  for (auto &entities_it : entities) { if (entities_it.second->ID_Parent != 0xffff) continue; found = true; Perform_destroy(entities_it.second); break; } 

Nice view of the cycle. Without auto it would be like this:


  for (std::pair<const u16, CSE_Abstract*> &entities_it : entities) { if (entities_it.second->ID_Parent != 0xffff) continue; found = true; Perform_destroy(entities_it.second); break; } 

As you understand, std::pair<const u16, CSE_Abstract*> will be a reference to the second subtitle, but oh well, there are such types not only in STD Namespace, but also in X-Ray itself. However, in such iterators there is another problem, but more on that later ...


And what is he bad?


1. The main problem is type ambiguity ...


Suppose we have a situation in the code:


 auto WhyIsWhy = TestPointer->GetCrows(); 

A person who has not written this code needs to quickly look at the contents of the function, run the IDE too long, use Notepad ++. He stumbles upon this line, and gets logic error The search for the GetCrows function declaration begins.


2. Link to an array object or let's talk more about Range-Base-For!


 LimbUpdate(CIKLimb &refLimb); ... { //   XRay Oxygen,   ,   , //   ,    for (auto it : _bone_chains) LimbUpdate(it); } 

It seems to be all right, but! We work not with an array element, but with a copy of an element object. Because of auto we do not see that it is not an object, but an object. Therefore, in places where we have a one-dimensional array, I advise you to write the types completely:


  for (CIKLimb &it : _bone_chains) LimbUpdate(it); 

3. And you have x64!


Those who worked with writing code for AMD64 know that the compiler loves double , not float . And our friend auto cast at compile time to the type preferred by the program. Consider an example.


 auto isFloat = 1.0; // 1.0f(x32) 1.0d(x64) 

Of course, such things are not critical, but the compiler may start to pour a bunch of warnings on truncation of types, which is not very pleasant, and besides, a permanent write to the log slows down the build. But, there are situations when such a casting plays a role. In cases with a natural number 'e' you need to be careful. For example:


 auto eps = 1e-8; 

In x32, this value is : 9.999999939e-09
In x64, this value is : 1.0000000000000021e-08


Conclusion


Of course, you decide where and how to use auto , but I prefer the full-fledged concept of static typing where it simplifies code understanding.


')

Source: https://habr.com/ru/post/424067/


All Articles