C++ Keywords - auto
auto
: the type of the variable will be automatically deduced.
Use cases
auto
can be overused. If the type is not obvious, prefer to specify the full type instead of using auto
.
Some acceptable usages are listed below.
In loops
// Without auto
for (const std::pair<const std::string, double>& entry : my_map) {
printf("%f\n", entry.second);
}
// With auto
for (const auto& entry : my_map) {
printf("%f\n", entry.second);
}
// With auto and structured bindings
for (const auto& [key, value] : my_map) {
printf("%f\n", value);
}
Iterators
// Without auto
absl::flat_hash_map<std::string, int>::const_iterator iter = m.find(val);
// With auto
auto iter = m.find(val);
unique_ptr
// Without auto
std::unique_ptr ptr = std::make_unique<int>(10);
// With auto
auto ptr = std::make_unique<int>(10);
Best Practice
Be precise
Be precise with use of auto. Knowing that things are constant or that indirections are occurring is very valuable information to readers.
auto
/const auto
auto&
/const auto&
: a reference to non-const / constauto*
/const auto*
: when the type is a pointer.
auto
For returned unique_ptr
If GetFoo
returns unique_ptr<Foo>
:
These 2 are equivalent:
const auto foo = GetFoo();
(Preferred)const auto& foo = GetFoo();
This does not compile.
const auto* foo = GetFoo();
auto* x = y
expects that y
is a C++ pointer. But std::unique_ptr<T>
is just an object that behaves like a pointer and takes care of ownership. Other than that, it is just a regular C++ class, not a regular pointer, like int*
.
Do not do:
const auto* foo = GetFoo().get();
It destructs the pointer when the statement ends, leaving thing as a dangling pointer.
GetFoo
will return a temporary object, you get the pointer to the underlying Foo*
and assign it to foo
. However as soon as that line is execute, the temporary unique_ptr
will be destroyed and the underlying Foo
object is freed, so now foo
is a dangling pointer to the freed memory.