@jupp0r
static type checking
checks are performed by the compiler at compile time
correct types are guaranteed for all program inputs
dynamic type checking
checks are performed at runtime
type inference
instead of variable types having to be explicitly declared, the compiler deduces types by usage
// template type deduction - you already know this
template <typename T>
T add(T a, T b) {
return a + b;
}
// auto type deduction - this is new in C++11
auto a = 12;
auto b = 3;
auto c = a + b; // 15
auto a = 12;
auto b = 3;
auto c = a + b;
auto a = 12;
auto b = 3;
auto c = a + b;
Almost
Always
Auto
Recommended by
std::vector<int> numbers = {5, 12, 45, 13};
int sum = 0;
for(std::vector<int>::const_iterator i =
numbers.cbegin();
i != numbers.cend();
i++) {
sum = sum + *i;
}
std::vector<int> numbers = {5, 12, 45, 13};
int sum = 0;
for(const auto i : numbers) {
sum = sum + i;
}
We'd like to change the container type of numbers
for(std::vector<int>::const_iterator i =
numbers.cbegin();
i != numbers.cend();
i++) {
sum = sum + *i;
}
We'd like to change the container type of numbers
for(const auto i : numbers) {
sum = sum + i;
}
No need to change anything.
int x; // uninitialized variable,
// reading its value is
// undefined behavior
auto y; // doesn't compile
auto z = 0; // variables declared as auto
// are guaranteed to be initialized
// at compile time
int sumWithAuto(int a, int b) {
auto sum =
[](int x, int y) {
return x + y;
};
return sum(a,b);
}
sumWithAuto(int, int):
lea eax, [rdi + rsi]
ret
recent clang and gcc compile this to
int sumWithoutAuto(int a, int b) {
std::function<int(int,int)> sum =
[](int x, int y) {
return x + y;
};
return sum(a,b);
}
gcc 6.1 compiles this to ...
std::_Function_handler<int (int, int), sumWithoutAuto(int, int)::
{lambda(int, int)#1}>::_M_invoke(std::_Any_data const&, int&&, std::_Any_data const&):
mov eax, DWORD PTR [rsi]
add eax, DWORD PTR [rdx]
ret
std::_Function_base::_Base_manager<sumWithoutAuto(int, int)::{lambda(int, int)#1}>::
_M_manager(std::_Any_data&, std::_Function_base::_Base_manager<
sumWithoutAuto(int, int)::{lambda(int, int)#1}> const&, std::_Manager_operation):
test edx, edx
je .L4
cmp edx, 1
jne .L3
mov QWORD PTR [rdi], rsi
.L3:
xor eax, eax
ret
.L4:
mov QWORD PTR [rdi], OFFSET FLAT:typeinfo for sumWithoutAuto(int, int)::{lambda(int, int)#1}
xor eax, eax
ret
sumWithoutAuto(int, int):
sub rsp, 40
lea ecx, [rdi+rsi]
mov edx, 3
mov rsi, rsp
mov rdi, rsp
mov QWORD PTR [rsp+24], OFFSET FLAT:
std::_Function_handler<int (int, int), sumWithoutAuto(int, int)::
{lambda(int, int)#1}>::_M_invoke(
std::_Any_data const&, int&&, std::_Any_data const&)
mov QWORD PTR [rsp+16], OFFSET FLAT:std::_Function_base::_Base_manager<
sumWithoutAuto(int, int)::{lambda(int, int)#1}>::_M_manager(std::_Any_data&,
std::_Function_base::_Base_manager<sumWithoutAuto(int, int)::
{lambda(int, int)#1}> const&, std::_Manager_operation)
call std::_Function_base::_Base_manager<sumWithoutAuto(int, int)::
{lambda(int, int)#1}>::_M_manager(std::_Any_data&,
std::_Function_base::_Base_manager<sumWithoutAuto(int, int)::
{lambda(int, int)#1}> const&, std::_Manager_operation)
add rsp, 40
mov eax, ecx
ret
No, it's all about
You already don't know the exact types that are used in your code, and that's good!
IDE is your friend
// error, not moveable
auto lock = std::lock_guard<std::mutex>{ m };
// error, not moveable
auto ai = std::atomic<int>{};