Implicit conversions are automatically performed by the compiler when needed.
double d{ 3 }; // int value 3 implicitly converted to type double
float doSomething() { return 3.0; } // double value 3.0 implicitly converted to type float
double division{ 4.0 / 3 }; // int value 3 implicitly converted to type double
if (5) {} // int value 5 implicitly converted to type bool
void doSomething(long l) {} doSomething(3); // int value 3 implicitly converted to type long
short s{ 3 }; // there is no short literal suffix, so we'll use a variable for this one
printInt(s); // numeric promotion of short to int
printInt('a'); // numeric promotion of char to int
printInt(true); // numeric promotion of bool to int
printDouble(4.0f); // numeric promotion of float to double
Note: A wider data type uses more bits, and a narrower data type uses fewer bits.
unsigned char
, char8_t
, and unsigned short
can be converted to int
if int
can hold the entire range of the type, or unsigned int
otherwise.char
follows either signed char
or unsigned char
rules based on its default signedness.bool
can be converted to int
, with false
becoming 0 and true
becoming 1.constexpr int n1{ 5 }; // note: constexpr
unsigned int u1 { n1 }; // okay: conversion is not narrowing due to exclusion clause
constexpr int n2 { -5 }; // note: constexpr
unsigned int u2 { n2 }; // compile error: conversion is narrowing due to value change
int x { 3.5 }; // brace-initialization disallows conversions that result in data loss
double d = 10 / 4; // does integer division, initializes d with value 2.0
double d = 10.0 / 4.0; // does floating point division, initializes d with value 2.5
(int)d // C-style cast, avoid using C-style casts.
int(d) // C++ version of C-style cast
static_cast(d) // C++-style cast
typeid
#include <typeinfo> // for typeid()
typeid(i + d).name()
std::cout << typeid(5u - 10).name() << ' ' << 5u - 10 << '\n'; // 5u means treat 5 as an unsigned integer
using Distance = double; // define Distance as an alias for type double
Distance milesToDestination{ 3.4 }; // defines a variable of type double
// file.h
#ifndef MYTYPES_H
#define MYTYPES_H
using Miles = long;
typedef long Miles; // same
using Speed = long;
#endif
#ifdef INT_2_BYTES
using int8_t = char;
using int16_t = int;
using int32_t = long;
#else
using int8_t = char;
using int16_t = short;
using int32_t = int;
#endif
using VectPairSI = std::vector<std::pair<std::string, int>>; // make VectPairSI an alias for this crazy type
auto
The auto
keyword allows the compiler to deduce the type of a variable from its initializer.
auto var{10};
auto sum { func(5, 6) }; // func() returns an int, so sum's type will be deduced to int
auto s { "Hello, world" }; // s will be type const char*, not std::string
using namespace std::literals; // easiest way to access the s and sv suffixes
auto s1 { "goo"s }; // "goo"s is a std::string literal, so s1 will be deduced as a std::string
auto s2 { "moo"sv }; // "moo"sv is a std::string_view literal, so s2 will be deduced as a std::string_view
auto foo() { return 5; } // no forward declaration for auto
auto add(int x, int y) -> int // trailing return syntax
{
return (x + y);
}