Expert · Modern C++: lambdas, C++17 and C++20 essentials · topic 31 of 42 · 25 min
auto, structured bindings and other C++17 conveniences
Explanation
auto: let the compiler write long type names
Types in C++ can get long: std::map<std::string, std::vector<int>>::const_iterator. auto tells the compiler to deduce the type from the initialiser. The variable still has one fixed type; auto just saves typing and avoids mistakes.
std::map<std::string, std::vector<int>> marksBySubject;
auto it = marksBySubject.find("Maths"); // instead of the long iterator type
auto count = 0; // int
auto price = 99.5; // double
auto name = std::string("Asha"); // std::string ("Asha" alone would be const char*)Structured bindings
#include <map>
#include <string>
#include <tuple>
std::pair<std::string, int> topper() { return {"Meena", 98}; }
auto [name, score] = topper(); // name = "Meena", score = 98
std::map<std::string, int> stock = {{"rice", 40}, {"dal", 25}};
for (const auto& [item, qty] : stock) {
std::cout << item << ": " << qty << '\n';
}
struct Point { int x; int y; };
auto [x, y] = Point{3, 4};
auto [it, inserted] = stock.insert({"oil", 10}); // insert returns (iterator, bool)
if (!inserted) std::cout << "already there\n";if and switch with an initialiser
if (auto it = stock.find("rice"); it != stock.end()) {
std::cout << "rice left: " << it->second << '\n';
} // it is not visible here
switch (auto code = getStatus(); code) {
case 200: break;
default: std::cout << "error " << code << '\n';
}Other small C++17 features
- [[nodiscard]] on a function makes the compiler warn if the caller ignores its return value: [[nodiscard]] bool save();.
- inline variables let you define a constant or static member in a header: inline constexpr double GST = 0.18;.
- Nested namespaces: namespace shop::billing { } instead of two nested blocks.
- std::size(container) and std::data(container) work for arrays and containers alike.
- Class template argument deduction: std::pair p{1, 2.5}; std::vector v{1, 2, 3}; without writing <int, double>.
constexpr if (if constexpr)
template <typename T>
std::string describe(const T& value) {
if constexpr (std::is_integral_v<T>) {
return "integer " + std::to_string(value);
} else {
return "something else";
}
}Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
auto, structured bindings and other C++17 conveniences · 1/6
C plus plus seventeen made everyday code much shorter. Let us see the most useful features.
Prefer a video by a teacher? Find free videos on “c++17 features structured bindings auto if initializer tutorial” on YouTube ↗
In real life: Reading results from a booking function
A bus booking function returns two things: whether the seat was booked and the PNR or an error code. Returning a struct and unpacking it with a structured binding makes the calling code read like a sentence.
#include <iostream>
#include <string>
struct BookingResult { bool ok; std::string pnr; };
BookingResult bookSeat(int seat) {
if (seat > 40) return {false, ""};
return {true, "BUS" + std::to_string(1000 + seat)};
}
int main() {
if (auto [ok, pnr] = bookSeat(12); ok) {
std::cout << "Booked, PNR " << pnr << '\n'; // Booked, PNR BUS1012
} else {
std::cout << "Seat not available\n";
}
}Practice (0/4 done)
auto x = 5 / 2; What is the type and value of x?
std::vector<int> v = {1, 2, 3}; for (auto x : v) x *= 10; What is v afterwards?
std::pair<int, std::string> p{7, "seven"}; auto [n, word] = p; What are n and word?
Write a function std::pair<int, int> minMax(const std::vector<int>& v) and use it with a structured binding. Then loop over a std::map<std::string, double> of item prices with const auto& [item, price] and print only items under Rs 100, using an if with initialiser to look up "tea" first.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- std::optional, std::variant and std::string_viewModern C++: lambdas, C++17 and C++20 essentials · same module
- C++20 ranges, views and other C++20 essentialsModern C++: lambdas, C++17 and C++20 essentials · same module
- Tuples: fixed groups of valuesPython Programming · Lists, tuples, dictionaries and sets
- StructsC Programming (from zero to systems) · Structs, unions, enums and files
- Constructors and destructorsClasses, constructors and RAII
- References: another name for a variableReferences, pointers, arrays and strings
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
auto s = "hello"; What is the type of s?
Answer: const char*
A string literal decays to const char*. Write std::string("hello") or use the "hello"s literal for std::string.
What can structured bindings unpack?
Answer: Pairs, tuples, std::array and structs with public members
They work with any tuple-like type and simple aggregates.
What does [[nodiscard]] do?
Answer: Asks the compiler to warn when the return value is ignored
It helps catch ignored error results.
Where is a variable declared in if (auto x = f(); x > 0) visible?
Answer: Only inside the if and its else
Its scope is the whole if statement, including else branches.
auto x = 10 / 4; What is x?Related
Answer: 2 (int)
10 / 4 is int division, giving 2, so auto makes x an int.
Which is a valid C++20 designated initialiser for struct P { int x; int y; };?Related
Answer: P p{.x = 1, .y = 2};
Designators use .name and must follow the declaration order.
When does the compiler choose which overload to call?Related
Answer: At compile time, from the argument types
Overload resolution happens while compiling, based on the arguments in each call.
Which of these is a tuple?Related
Answer: (1, 2)
Round brackets with commas make a tuple. Square brackets make a list, and curly braces make a set.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Modern C++: lambdas, C++17 and C++20 essentials” before its exam: std::optional, std::variant and std::string_view, C++20 ranges, views and other C++20 essentials.
- Module 8 exam: Modern C++ · 12 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Exceptions, concurrency and building projects with CMake. 42 topics left in the course before the final exam.