Skip to content
Laviyx Learn

Try

C++ course menu

C++ Type Conversion: Implicit Conversion, static_cast and String Conversions

Learn how C++ converts between types: implicit conversions and promotions, truncation and narrowing, explicit casts with static_cast, why to avoid C-style casts, and converting between numbers and strings with std::to_string and std::stoi.

Beginner8 min readUpdated
On this page

Values often need to change type: an int count used in a decimal average, a double price rounded to whole rupees, or text typed by a user turned into a number. C++ converts some types automatically and makes you ask explicitly for others.

Implicit conversions#

When you mix types in an expression, C++ converts the "smaller" type to the "larger" one before calculating:

C++
#include <iostream>

int main() {
    int apples = 7;
    double weight = 0.25;

    std::cout << apples * weight << '\n';  // int converted to double
    std::cout << 'A' + 1 << '\n';          // char promoted to int
}
Output
1.75
66

Converting int to double is safe. The other direction is not: storing a double in an int drops the fractional part (it does not round):

C++
#include <iostream>

int main() {
    double price = 99.99;
    int rupees = price;       // compiles, with a warning under -Wconversion
    int negative = -3.9;

    std::cout << rupees << ' ' << negative << '\n';
}
Output
99 -3

Truncation goes towards zero: 99.99 becomes 99 and −3.9 becomes −3. This silent data loss is why brace initialization (int rupees{price};) refuses to compile it.

Explicit conversion with static_cast#

When you want a conversion, say so with static_cast<Type>(value). It makes the intent visible to readers and quiets warnings:

C++
#include <iostream>

int main() {
    int total_marks = 437;
    int subjects = 5;

    double wrong = total_marks / subjects;
    double average = static_cast<double>(total_marks) / subjects;

    std::cout << wrong << ' ' << average << '\n';
}
Output
87 87.4

total_marks / subjects divides two integers and gives 87, before the result is stored in the double. Casting one operand first makes the division happen in floating point.

Rounding properly#

To round instead of truncate, use the functions in <cmath>:

C++
#include <cmath>
#include <iostream>

int main() {
    double x = 2.5;
    double y = -2.7;

    std::cout << std::round(x) << ' ' << std::floor(x) << ' ' << std::ceil(x) << '\n';
    std::cout << std::round(y) << ' ' << std::trunc(y) << '\n';
    std::cout << static_cast<int>(std::round(4.6)) << '\n';
}
Output
3 2 3
-3 -2
5
FunctionMeaning
std::roundNearest whole number (halves go away from zero)
std::floorRound down
std::ceilRound up
std::truncDrop the fraction (towards zero)

These return a double; cast the result if you need an int.

Avoid C-style casts#

Old code (and C) writes casts as (int)price or int(price). These C-style casts try several kinds of conversion, including dangerous ones, without telling you which. Prefer static_cast. C++ has three other named casts for special situations (const_cast, reinterpret_cast, dynamic_cast); you will meet dynamic_cast in Polymorphism.

Numbers to strings and back#

Converting between text and numbers uses functions from <string>:

C++
#include <iostream>
#include <string>

int main() {
    int age = 21;
    std::string message = "Age: " + std::to_string(age);
    std::cout << message << '\n';

    std::string input = "42";
    int n = std::stoi(input);      // string to int
    double d = std::stod("3.75");  // string to double
    std::cout << n + 1 << ' ' << d * 2 << '\n';
}
Output
Age: 21
43 7.5

std::stoi reads digits from the start of the string and stops at the first character that is not part of a number, so std::stoi("42kg") gives 42. If there is no number at all, it throws an exception (std::invalid_argument):

C++
#include <iostream>
#include <stdexcept>
#include <string>

int main() {
    try {
        int n = std::stoi("abc");
        std::cout << n << '\n';
    } catch (const std::invalid_argument&) {
        std::cout << "Not a number\n";
    }
}
Output
Not a number

You will learn about try and catch in Exceptions.

FunctionConverts
std::to_string(x)number → std::string
std::stoi(s)string → int
std::stoll(s)string → long long
std::stod(s)string → double

char and digits#

A digit character such as '7' is not the number 7; its character code is 55. Subtract '0' to get the digit's value:

C++
#include <iostream>

int main() {
    char c = '7';
    int digit = c - '0';
    std::cout << digit * 2 << '\n';
}
Output
14

Common mistakes#

Practice#

Practice exercise

A runner covered 21 km in 125 minutes. Print the average speed in km per hour, rounded to the nearest whole number, as an int. Then build the string "Speed: 10 km/h" with std::to_string and print it.

Show hint

Speed is km / (minutes / 60.0). Round with std::round, then static_cast<int>.

Show solution
C++
#include <cmath>
#include <iostream>
#include <string>

int main() {
    int km = 21;
    int minutes = 125;

    double speed = km / (minutes / 60.0);
    int rounded = static_cast<int>(std::round(speed));

    std::string text = "Speed: " + std::to_string(rounded) + " km/h";
    std::cout << text << '\n';
}
Output
Speed: 10 km/h

The exact speed is 10.08 km/h, which rounds to 10.

Key takeaway#

Finished this lesson?