Clause 6 of "Effective Modern C++" study notes: When the type deduced by auto does not meet the requirements, use the initialization with display type

Although the use of auto is indeed beneficial, it is not a panacea by then. In some scenarios, we have to use the initialization with display type. For example, the following code:

std::vector<bool> features() {
     std::vector<bool> temp;
     for(int i = 0;i < 10; ++i) {
         temp.push_back(true);
     }
     
     return temp;
}

auto result = features()[5];//错误,将导致未定义行为

bool result2 = features()[5];//正确

The above code is very simple. A function returns a vector object with 10 trues in it, and then uses auto to receive the sixth value (calculated from 0). We take it for granted that the value of result is of type bool at this time, but in reality The above is not, std::vector<T> has special treatment for bool type and only has special treatment for bool type. The return value is not bool, but std::vector<bool>::reference type. The reason for this result is that STL has done a special to the operator[] function of std::vector<bool>, using a compressed way to express the bool elements it holds, that is, each bool element uses one Bits to represent. Normally, the operator[] function of std::vector<T> should return T&, but C++ prohibits bit reference, so the operator[] function of std::vector<bool> returns std:: The vector<bool>::reference type, and the std::vector<bool>::reference type has done an implicit conversion to the bool type. It is precisely because of this implicit conversion that we can use the bool type To receive std::vector<bool>::reference.

The above std::vector<bool> is actually a scenario where a proxy class is used. std::vector<bool>::reference is a proxy for bool. You may ask, how do we know whether certain library functions use a proxy? ? The method is very simple, look at the source code. The source code can be seen, but if you have to look at the source code every time you use a library function, it will undoubtedly reduce our development efficiency, so here is a once and for all method: use the initialization with display type, say The blunt point is to perform display coercive type conversion before assignment. Not only for the operator[] function of std::vector<bool>, when using auto to receive the value of certain expressions, it is best to use initialization with display types. For example, the auto statement in the above code can be changed to this :

auto result = static_cast<bool>(features()[5]);

auto sum = static_cast<MyType>(m1 + m2 + m3);

auto index = static_cast<int>(d * c.size());

 

Shorthand

  • The invisible proxy type may cause the type deduced by auto based on the initialization expression to be wrong
  • Initialization with display type, you can force auto to deduce the type you want

 

Guess you like

Origin blog.csdn.net/Chiang2018/article/details/114047768