auto keywordUsing auto, the compiler deducts variable types based
on their initial value
The rules for type inference are essentially the same used for templates
autoUsing auto makes your code more resilient and readable.
auto variables
have to be initializedautoTo better understand what auto does,
check the deducted types
typeid(.).name() denotes the implementation defined name of
the type
ABI for C++ programs contains information on builtin types
#include <iostream>
#include <typeinfo>
int main() {
int x{42};
std::cout << "Type of x: " << typeid(x).name() << "\n"; // output: i
const int ci{42};
std::cout << "Type of ci: " << typeid(ci).name() << "\n"; // output: i
unsigned long int uli{42};
std::cout << "Type of uli: " << typeid(uli).name() << "\n"; // output: m
double d{3.14};
std::cout << "Type of d: " << typeid(d).name() << "\n"; // output: d
return 0;
}
auto#include <iostream>
#include <typeinfo>
#include <vector>
using std::string_literals::operator""s; // required for the `s` suffix
template <typename T>
void print_type(const char* name, T arg) {
std::cout << "Type of " << name << ": " << typeid(arg).name() << std::endl;
}
int main() {
auto i{42};
print_type("i", i); // i(nt)
const auto ci{42};
print_type("ci", ci); // i(nt)
print_type("ui", 42u); // j
print_type("l", 42l); // l
auto ul{42ul};
print_type("ul", ul); // m
auto ull{42ull};
print_type("ull", ull); // y
auto f{3.14f};
print_type("f", f); // f
print_type("d", 3.14); // d
auto s{"foo"};
print_type("s", s); // PKc
auto str = "foo"s;
print_type("str", str); // Ss
return 0;
}
#include <iostream>
#include <typeinfo>
#include <vector>
template <typename T>
void print_type(const char* name, T arg) {
std::cout << "Type of " << name << ": " << typeid(arg).name() << std::endl;
}
int main() {
auto v{std::vector<int>{1, 2, 3}};
print_type("v", v); // [...]vector[...]
auto p{std::pair<int, char>{2, 1}};
print_type("p", p); // [...]pair[...]
return 0;
}
#include <iostream>
#include <string>
#include <vector>
int main() {
auto v{std::vector<std::string>(3, "foo")};
for (std::vector<std::string>::const_iterator it{v.cbegin()}; it != v.cend(); ++it) {
std::cout << *it << ", ";
}
for (auto it{v.cbegin()}; it != v.cend(); ++it) {
std::cout << *it << ", ";
}
std::cout << std::endl;
return 0;
}
#include <functional>
#include <iostream>
#include <vector>
std::function<std::vector<int>::size_type(const std::vector<int>&,
const std::vector<int>&)>
sum_sizes = [](const std::vector<int>& v1, const std::vector<int>& v2)
{ return v1.size() + v2.size(); };
int main() {
auto v1{std::vector<int>{1, 2, 3}};
auto v2{std::vector<int>(4, 5)};
std::cout << "total size of v1 and v2: " << sum_sizes(v1, v2) << "\n";
return 0;
}
Download lambda.cpp
#include <iostream>
#include <vector>
auto sum_sizes = [](const std::vector<int>& v1, const std::vector<int>& v2)
{ return v1.size() + v2.size(); };
int main() {
auto v1{std::vector<int>{1, 2, 3}};
auto v2{std::vector<int>(4, 5)};
std::cout << "total size of v1 and v2: " << sum_sizes(v1, v2) << "\n";
return 0;
}
Download lambda_auto.cpp
#include <iostream>
#include <vector>
auto sum_sizes = [](const auto& v1, const auto& v2)
{ return v1.size() + v2.size(); };
int main() {
auto v1{std::vector<int>{1, 2, 3}};
auto v2{std::vector<int>(4, 5)};
std::cout << "total size of v1 and v2: " << sum_sizes(v1, v2) << "\n";
return 0;
}
Download lambda_all_auto.cpp
Sometimes, auto may deduce undesired types
Scott Meyers' explicitly typed initializer idiom can be used instead of falling back to explicit typing
Type value{get_value()}; // explicit typing
auto value{static_cast<Type>(get_value())}; // explicitly typed initializer
Embedded system must store the result of external code as
float
#include <iostream>
double get_value () { return 0.5; }; // dummy for external calculation
int main() {
auto d{get_value()}; // not the desired type
std::cout << "Type of d: " << typeid(d).name() << "\n";
// float f0{get_value()}; // compiler error
// std::cout << f0 << "\n";
float f1 = get_value(); // possible compiler warning (-Wconversion)
float f2{static_cast<float>(get_value())}; // duplication of type
auto val{static_cast<float>(get_value())};
std::cout << "val: " << val << " f1: " << f1 << " f2: " << f2 << "\n";
return 0;
}
Download etii.cpp
Almost always auto (AAA) unless you have a reason not to
auto variables must be initializedauto to
deduce desired type