DEV Community

Cover image for The awesome `auto` keyword
Alberto Pérez de Rada Fiol
Alberto Pérez de Rada Fiol

Posted on

The awesome `auto` keyword

In modern C++, you write auto auto(auto auto) { auto; } and the compiler infers the rest

Ok, it's not that easy, but I promise that using auto does indeed feel like magic. Let's go with the first article with actual content of the Learning modern C++ series!

The auto keyword is used to let the compiler infer the type of a variable automatically from its initial value instead of having to explicitly declare it. (Bonus: forget about uninitialized variables!) For instance:

// Older standards
int i = 0;

// Modern C++
auto i = 0;
Enter fullscreen mode Exit fullscreen mode

At first, this may not seem like a huge deal, but let's see another example. If we have a getMatrix function that returns a std::vector<std::vector<int>> type, we can easily print all its elements with a range-based for loop (if you don't know what a range-based for loop is, you'll love the next article of this series!). In this example, you'll see how auto starts to shine a bit more:

// Older standards
std::vector<std::vector<int>> matrix = getMatrix();
for (std::vector<int> row : matrix) {
  for (int element : row) {
    std::cout << element << std::endl;
  }
}

// Modern C++
auto matrix = getMatrix();
for (auto row : matrix) {
  for (auto element : row) {
    std::cout << element << std::endl;
  }
}
Enter fullscreen mode Exit fullscreen mode

Hey, isn't that cool? 😎 And it gets even better! What would happen if the getMatrix function was changed to return a std::vector<std::vector<double>> type instead? With older C++ standards, we would have to adapt our code in order for it to work again, but using the modern C++ auto keyword we wouldn't need to touch anything!

Of course, this gets even more meaningful in real-world examples, but I think the ones presented should be enough to at least spark some interest.

auto can also be used in function declarations, although I must admit that I haven't committed to it (yet?). The syntax is:

// Older standards
int getIntParameter(int parameter) { return parameter; }

// Modern C++
auto getIntParameter(int parameter) -> int { return parameter; }
Enter fullscreen mode Exit fullscreen mode

However, it can be very useful when used in conjunction with the decltype specifier (which inspects the declared type of a varibale):

template <typename T, typename U>
auto sum(T t, U u) -> decltype(t + u) { return t + u; }
Enter fullscreen mode Exit fullscreen mode

Note that in the example above we don't know the types t and u, but we don't even need it! We could call the function like:

auto x = sum(1, 1); // (int) 2
auto y = sum(1, 0.14); // (double) 1.14
auto pi = sum(x, y); // (double) 3.14
auto tau = sum(pi, pi); // (double) 6.28
Enter fullscreen mode Exit fullscreen mode

And everything will work wonderfully 🎉

That's probably enough for the post, let me know what you think of it on the comments section below! Reacting to and sharing the post is also appreciated 😊 And, as always, thanks for reading!

Discussion (4)

Collapse
pauljlucas profile image
Paul J. Lucas • Edited on

auto i = 0;

Except that doesn't always mean what you think it means. If you originally did:

unsigned i = 0;
Enter fullscreen mode Exit fullscreen mode

then the type of i is unsigned (obviously); but if you change that to auto as above, then the type of i becomes int because 0 is an int literal. If you want it to stay unsigned, then you have to be explicit:

auto i = 0u;
Enter fullscreen mode Exit fullscreen mode

You have the same problem for short, long, long long, and their unsigned variants.

for (std::vector<int> row : matrix) {

This is incorrect. In the "older standards" (C++03 and earlier), range-based for loops weren't a thing yet. (Even if they were, it's still incorrect since you're missing ::const_iterator.) Range-based for loops were addd to C++ at the same time as auto in C++11, so your "older standards" code should have been:

for (std::vector<int>::const_itererator i = maxtrix.begin(); i != matrix.end(); ++i ) {
Enter fullscreen mode Exit fullscreen mode
Collapse
pgradot profile image
Pierre Gradot

And remember that const is a really good friend of auto. Together, they are a perfect couple for modern C++ ^^

Collapse
sandordargo profile image
Sandor Dargo

Nice article, thanks! Here is a great article by Herb Sutter, in case you want to dive even deeper.

Collapse
albertopdrf profile image
Alberto Pérez de Rada Fiol Author

Thanks for the comment and the reference Sandor, it's much appreciated! 😊