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!

Top comments (4)

Collapse
 
pauljlucas profile image
Paul J. Lucas • • Edited

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
 
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 •

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

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++ ^^