Type Conversion/Casting Confusion in C++

Ell picture Ell · Dec 2, 2010 · Viewed 7.1k times · Source

What is Type Conversion and what is Type Casting?

When should I use each of them?

Detail: Sorry if this is an obvious question; I'm new to C++, coming from a ruby background and being used to to_s and to_i and the like.

Answer

Steve Jessop picture Steve Jessop · Dec 2, 2010

Conversion is when a value is, um, converted to a different type. The result is a value of the target type, and there are rules for what output value results from what input (of the source type).

For example:

int i = 3;
unsigned int j;
j = i; // the value of "i" is converted to "unsigned int".

The result is the unsigned int value that is equal to i modulo UINT_MAX+1, and this rule is part of the language. So, in this case the value (in English) is still "3", but it's an unsigned int value of 3, which is subtly different from a signed int value of 3.

Note that conversion happened automatically, we just used a signed int value in a position where an unsigned int value is required, and the language defines what that means without us actually saying that we're converting. That's called an "implicit conversion".

"Casting" is an explicit conversion.

For example:

unsigned int k = (unsigned int)i;
long l = long(i);
unsigned int m = static_cast<unsigned int>(i);

are all casts. Specifically, according to 5.4/2 of the standard, k uses a cast-expression, and according to 5.2.3/1, l uses an equivalent thing (except that I've used a different type). m uses a "type conversion operator" (static_cast), but other parts of the standard refer to those as "casts" too.

User-defined types can define "conversion functions" which provide specific rules for converting your type to another type, and single-arg constructors are used in conversions too:

struct Foo {
    int a;
    Foo(int b) : a(b) {}                   // single-arg constructor
    Foo(int b, int c) : a(b+c) {}          // two-arg constructor
    operator float () { return float(a); } // conversion function
};

Foo f(3,4);              // two-arg constructor
f = static_cast<Foo>(4); // conversion: single-arg constructor is called
float g = f;             // conversion: conversion function is called