The book recommends the use of auto instead of explicit types. He does warn against using auto when proxy classes are involved. One example is std::vector<bool>. Using the operator[] on a std::vector<bool> yields a std::vector<bool>::reference (a proxy class) instead of a simple bool.
Consider this example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <iostream> | |
const bool MAGIC_VALUE = true; | |
std::vector<bool> features() | |
{ | |
std::vector<bool> tmp; | |
tmp.push_back(false); | |
tmp.push_back(MAGIC_VALUE); | |
tmp.push_back(false); | |
return tmp; | |
} | |
int main() | |
{ | |
const int MAX_RUNS = 100; | |
int num_correct = 0; | |
for (int i = 0; i < MAX_RUNS; ++i) | |
{ | |
auto b = features()[1]; | |
//auto b = static_cast<bool>(features()[1]); | |
if (b == MAGIC_VALUE) | |
{ | |
++num_correct; | |
} | |
} | |
std::cout << num_correct << "/" << MAX_RUNS << std::endl; | |
return 0; | |
} |
So in the example, in line 22, b is of type std::vector<bool>::reference which contains a pointer to some memory location. Note, however, that features() returns a temporary std::vector<bool> which goes out of scope as soon as line 22 finishes execution. Thus, after line 22 is executed, the word (memory location) which contains the boolean goes out of scope. The pointer within b then becomes a dangling pointer pointing to who knows what.
When the code is executed:
nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
0/100
If line 23 is executed instead of line 22:
nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
100/100
Meyers calls the style used in line 23 as "the explicitly typed initializer idiom".
No comments:
Post a Comment