While it might seem safer to require exact types everywhere, implicit conversions actually make programming more practical and convenient. Let's look at why we have them:
In math class, we freely mix different types of numbers. We can add whole numbers and decimals without thinking about it:
#include <iostream>
using namespace std;
int main() {
// In math: 5 + 3.14 is perfectly normal
float Sum{5 + 3.14f};
cout << "5 + 3.14 = " << Sum << "\n";
// We often mix whole numbers and decimals
// Starting position
float PlayerX{10};
// Move half a unit right
PlayerX = PlayerX + 0.5f;
cout << "Player position: " << PlayerX;
}
5 + 3.14 = 8.14
Player position: 10.5
Without implicit conversions, we'd have to write extra code to convert numbers every time we mix types:
int main() {
// Without implicit conversions, we'd need
// explicit conversions everywhere
float Sum{static_cast<float>(5) + 3.14f};
float PlayerX{static_cast<float>(10)};
}
Implicit conversions help with everyday programming tasks. For example, checking if a number is non-zero:
#include <iostream>
using namespace std;
int main() {
int Score{100};
// This is clear and simple
if (Score) {
cout << "Player has points!\n";
}
// Without implicit conversions, we'd need:
if (Score > 0) {
cout << "This is more complicated than"
" needed!";
}
}
Player has points!
This is more complicated than needed!
C++ does try to protect us from dangerous conversions. Remember how using { }
for initialization prevents narrowing:
int main() {
// This could lose data - C++ prevents it
int DangerousInt{3.14f};
// We have to be explicit if we really want to do this
int IntentionalInt{static_cast<int>(3.14f)};
}
error C2397: conversion from 'float' to 'int' requires a narrowing conversion
So C++ gives us the best of both worlds:
Answers to questions are automatically generated and may not have been reviewed.
Going into more depth on what is happening when a variable is used as a different type