1. Problem It Solves
Given const int source = 1;, why does auto value = source; create a mutable int? auto deduces a type from the initializer; & and const in the declaration determine whether the new variable holds a separate value or refers to an existing object.
2. Prerequisites
Variable declarations,
const, pointers, andT&references.The difference between creating a new variable and referring to an existing object.
3. Core Idea
auto uses rules similar to template argument deduction. With auto value = source, the new variable does not retain the source's reference or outermost const/volatile. With auto& view = source, the reference preserves the referred object's constness.
Constness inside a pointer type survives: copying a const int* with auto still gives const int*. This does not permit modifying a const int through the new pointer.
4. Minimal Syntax
const int source = 1;
auto value = source;
auto& view = source;
const auto& read_only = value;value is int; both view and read_only are const int&. Assigning value = 2 is valid and leaves source unchanged.
5. How It Works
Read the whole declaration:
auto,auto&,const auto&, orauto&&.Value deduction with
autousually converts array and function types to pointers. Reference forms can preserve the array or function type.With
auto&& r = expression, an lvalue such as anintvariable givesint&; a temporary expression such as42givesint&&. Deduction and reference collapsing produce these results.Check braces separately: in C++20,
auto one{1}givesint, whileauto list = {1}givesstd::initializer_list<int>and needs<initializer_list>.auto bad{1, 2}is invalid;auto mixed = {1, 2.0}also fails to deduce a common element type.
6. Common Mistakes
Assuming
autoalways preserves the source variable's exact type.Assuming it removes every
const, including the constness of a pointed-to object.Using
autoin a loop when intending to modify the original elements; that usually needsauto&.Assuming a reference automatically extends every object's lifetime. A reference to a destroyed object remains unusable.
7. When to Use It
Use auto when the initializer makes the type clear or the type is lengthy, such as an iterator. Choose auto& to modify original elements and const auto& to read without copying. Write an explicit type when you want a particular conversion.
8. Simple Example
The C++20 sample checks two types at compile time:
const int source = 1;
auto value = source;
const auto& view = source;
static_assert(std::is_same_v<decltype(value), int>);
static_assert(std::is_same_v<decltype(view), const int&>);std::is_same_v requires <type_traits>. The program prints nothing; successful compilation confirms both checks.
Complete sample code
Source file
dailycppinterview/001_auto-type-deduction/main.cpp
// Real-World C++ Interviews Q001: Explain auto type deduction!
// Key: `auto` follows template-style deduction: top-level references and cv-qualifiers may be
// dropped according to the declaration form, while braced initializers have special
// `std::initializer_list` rules. Write `auto&`, `const auto&`, or `auto&&` when reference
// behavior is part of the contract.
#include <type_traits>
int main() {
const int source = 1;
auto value = source;
const auto& view = source;
static_assert(std::is_same_v<decltype(value), int>);
static_assert(std::is_same_v<decltype(view), const int&>);
}
9. Key Takeaways
auto determines a static type at compile time. First decide whether you need a separate value or a reference, then check constness and the initializer form.
10. Self-Check Question
Full question: Explain auto type deduction!
Given const int x = 7;, determine the types of auto a = x, auto& b = x, and auto&& c = x. Which variable can you modify directly? Why does auto d{7} differ from auto e = {7}?