Auto Forgetfulness
The other day, I started tracking down a defect in my C++11 code that was exposed by a unit test. At first, I thought the bugger had to be related to the domain logic I was implementing. However, after 4 hours of inspection/testing/debugging, the answer simply popped into my head, seemingly out of nowhere (funny how that works, no?). It was due to my “forgetting” a subtle characteristic of the C++11 automatic type deduction feature implemented via the “auto” keyword.
To elaborate further, take a look at this simple function prototype:
SomeReallyLongTypeName& getHandle();
On first glance, you might think that the following call to getHandle() would return a reference to an internal, non-temporary, object of type SomeReallyLongTypeName that resides within the scope of the getHandle() function.
auto x = getHandle();
However, it doesn’t. After execution returns to the caller, x contains a copy of the internal, non-temporary object of type SomeReallyLongTypeName. If SomeReallyLongTypeName is non-copyable, then the compiler would have mercifully clued me into the problem with an error message (copy ctor is private (or deleted)).
To get what I really want, this code does the trick:
auto& x = getHandle();
The funny thing is that I already know “auto” ignores type qualifications from routinely writing code like this:
std::vector<int> vints{}; //fill up "vints" somehow for(auto& elem : vints) { //do something to each element of vints }
However, since it was the first time I used “auto” in a new context, its type-qualifier-ignoring behavior somehow slipped my feeble mind. I hate when that happens.
This is a good chance to use decltype(auto).