Type Conversions
Values often need converting: an int to a double for division, text from the user into a number, a number into text. C++ does some conversions implicitly, provides named casts for explicit ones, and has library functions for converting between strings and numbers.
Implicit conversions
In mixed arithmetic, the narrower type is converted to the wider one. Assigning to a narrower type converts too — silently losing data:
#include <iostream> int main() { int items = 7; double weight = 0.5; std::cout << items * weight << '\n'; // int converted to double double precise = 9.99; int truncated = precise; // fraction dropped std::cout << truncated << '\n'; }
3.5 9
Brace initialisation refuses such narrowing (lesson 4), and -Wconversion warns about it.
static_cast
To convert explicitly, use static_cast<Type>(value). It's easy to search for and says clearly that the conversion is intentional:
#include <iostream> int main() { int total = 17, count = 4; std::cout << total / count << '\n'; // 4: integer division std::cout << static_cast<double>(total) / count << '\n'; // 4.25 double price = 19.99; int whole = static_cast<int>(price); char letter = static_cast<char>(65); std::cout << whole << ' ' << letter << '\n'; }
4 4.25 19 A
C++ has three other named casts for special situations — const_cast (removing const), reinterpret_cast (reinterpreting raw bits) and dynamic_cast (checked down-casts in class hierarchies, lesson 37). C-style casts like (int) x still work but can silently do any of these, so prefer the named forms.
Rounding
Casting to an integer truncates toward zero. For rounding, use <cmath>:
#include <cmath> #include <iostream> int main() { for (double v : {2.5, 2.4, -2.5, -2.6}) { std::cout << v << ": cast " << static_cast<int>(v) << ", round " << std::round(v) << ", floor " << std::floor(v) << ", ceil " << std::ceil(v) << '\n'; } }
2.5: cast 2, round 3, floor 2, ceil 3 2.4: cast 2, round 2, floor 2, ceil 3 -2.5: cast -2, round -3, floor -3, ceil -2 -2.6: cast -2, round -3, floor -3, ceil -2
Strings to numbers
std::stoi, std::stol and std::stod parse a string. They throw an exception if no number can be read, and report how many characters they used:
#include <iostream> #include <stdexcept> #include <string> int main() { for (std::string text : {"42", "3.75", "12abc", "abc"}) { try { std::size_t used = 0; int n = std::stoi(text, &used); std::cout << text << " -> " << n; if (used < text.size()) std::cout << " (ignored \"" << text.substr(used) << "\")"; std::cout << '\n'; } catch (const std::invalid_argument&) { std::cout << text << " -> not a number\n"; } } std::cout << std::stod("3.75") * 2 << '\n'; }
42 -> 42 3.75 -> 3 (ignored ".75") 12abc -> 12 (ignored "abc") abc -> not a number 7.5
Exceptions are covered in lesson 42. For the fastest parsing with no exceptions, <charconv> provides std::from_chars:
#include <charconv> #include <iostream> #include <string_view> int main() { std::string_view text = "2048 bytes"; int value = 0; auto [ptr, error] = std::from_chars(text.data(), text.data() + text.size(), value); if (error == std::errc{}) { std::cout << "parsed " << value << ", rest: \"" << ptr << "\"\n"; } }
parsed 2048, rest: " bytes"
Numbers to strings
#include <format> #include <iostream> #include <string> int main() { std::string a = std::to_string(42); std::string b = std::to_string(3.5); // always 6 decimals std::string c = std::format("{:.2f}", 3.14159); // full control (C++20) std::cout << a + " | " + b + " | " + c << '\n'; }
42 | 3.500000 | 3.14
std::format (lesson 45) is the flexible choice; std::to_string is the quick one.
Characters and digits
#include <iostream> int main() { char digit = '7'; int value = digit - '0'; // '0'..'9' are consecutive codes char next = static_cast<char>('a' + 1); std::cout << value * 2 << ' ' << next << ' ' << static_cast<int>('A') << '\n'; }
14 b 65
Try it yourself
Read lines of input, convert each to a number if possible, and print the sum of the valid ones.
12.5 seven 30 1e2
skipping "seven" sum = 142.5