C++ Tips : Type Deduction
Type deduction, Reference Collapsing.
C++ Tips : Type Deduction
My C++ Tips
Type Deduction
What is type deduction?
- Compiler’s ability to automatically determine the type of a variable or expression.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
auto i = 10; // int
auto d = 3.14; // double
auto b = i > d; // bool
int ar[] = {1, 2};
auto p1 = ar; // int*
int x = 10;
const int cx = 5;
auto a = x; // int
auto b = cx; // still int , NOT const int
int* const p2 = &x;
auto c = p2; // int*
const int* p3 = &x;
auto d = p3; // const int*
int& r = x;
auto b = r; // int , NOT int&
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int x = 1;
int* p1 = &x;
const auto p2 = p1; // int* const
const int cx = 1;
auto& y = cx; // const int&
int a = 1;
int* const b = &a;
auto& c = b; // int* const&
auto& s = "Hello"; // const char(&)[6]
auto x[]; // error: auto requires initializer
The type of a variable can be a reference, but the type of an expression CAN’T
1
2
3
4
5
6
7
8
9
int x = 1;
int& r1 = x;
const int& r2 = x;
auto a = r1; // int
auto b = r2; // int
int&& r = 10;
auto c = r; // int
Type deduction : ternary operator
1
2
3
4
5
6
7
int x = 2, y = 4;
double z = 5.5;
auto i = x > 3 ? y : z;
// auto : double
// ternary operator is run-time process but
// type deduction is compile-time process
Type deduction : array
1
2
3
int arr[5] = {1, 2, 3, 4, 5};
auto p3 = arr; // int*
auto& p4 = arr; // int(&)[5]
Type deduction : func pointer
1
2
3
4
5
6
7
8
9
10
11
using F = int(int);
using FP = int(*)(int);
int foo() { return 0; }
auto fp1 = foo; // int(*)(int)
auto fp2 = &foo; // int(*)(int)
// They are same
auto f3 = foo; // int(*)(int)
auto& f4 = foo; // int(&)(int)
Reference Collapsing
&
&
becomes&
&
&&
becomes&
&&
&
becomes&
&&
&&
becomes&&
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef int& lref;
typedef int&& rref;
int n;
// & & -> &
lref& r1 = n; // type of r1 is int&
// & && -> &
lref&& r2 = n; // type of r2 is int&
// && & -> &
rref& r3 = n; // type of r3 is int&
// && && -> &&
rref&& r4 = 1; // type of r4 is int&&
Why do we need it?
- Reference collapsing enables perfect forwarding by preserving value categories.
- T&& can be called with both lvalue and rvalue.
1
2
3
4
5
6
template<typename T>
void wrapper(T&& arg)
{
// T&& = forwarding reference
process(std::forward<T>(arg));
}


This post is licensed under CC BY 4.0 by the author.