Skip to content

Type deduction

Type deduction

The auto keyword declares a variable whose type is deduced from the initialization expression in its declaration.

Auto for fundamental data types:

  • Avoid using auto for fundamental data types!
  • This is a bad place for auto
  • It does not avoid a long type name
  • It creates ambiguity
    • auto x = 87 could semantically be any number type
  • This is somewhat equivalent to:
  • swift: var dont_do_that = 87
  • rust: let mut dont_do_that = 87

On the other hand, auto is very useful in generic functions where there types are not ambiguous.

1
2
auto dont_do_that = 87;
std::cout << "dont_do_that: " << dont_do_that << '\n';

1
2
3
4
std::unordered_map<std::string, double> t;
t["zero"] = 0.0;
t["pi"] = 3.14;
t["ten"] = 10.0;

1
2
3
4
5
// NOLINTNEXTLINE(modernize-use-auto)
std::unordered_map<std::string, double>::iterator it = t.find("pi");
if (it != t.end()) {
    std::cout << it->first << ": " << it->second << '\n';
}

1
2
3
4
5
6
7
8
// This is the perfect place for auto
// - It avoids a long type name
// - There's no ambiguity
//   - Find will always return an iterator
auto it2 = t.find("zero");
if (it2 != t.end()) {
    std::cout << it2->first << ": " << it2->second << '\n';
}

1
2
3
4
5
6
decltype(it) it3;
it3 = it;
++it3;
if (it3 != t.end()) {
    std::cout << it3->first << ": " << it3->second << '\n';
}

1
2
3
4
5
6
auto print_map_container = [](const auto &m) {
    for (auto &&item : m) {
        std::cout << item.first << ": " << item.second << '\n';
    }
};
print_map_container(t);

Share Snippets