CodeNebula
C++11coreintermediate

Type Traits (C++11 Addition)

C++11 · Modern Revolution · Compiler flag: -std=c++11

Explanation

Provides compile-time type information (e.g., `is_integral`).

Real-World Scenario

Check if a type is integral in a generic algorithm.

Quick Snippet

snippet.cpp
#include <type_traits> std::is_integral<int>::value;

Full Example

type_traits.cpp
// CodeNebula - C++11 Example: Type Traits Overview
// Compile: g++ -std=c++11 -Wall -Wextra -o example type_traits.cpp

// Demonstrates the <type_traits> header: compile-time type inspection and
// transformation utilities. Type traits enable SFINAE, static dispatch, and
// generic programming by querying properties of types at compile time.

#include <iostream>
#include <type_traits>
#include <string>
#include <vector>

// Real-world scenario: optimized copy for trivially copyable types
template <typename T>
void smartCopy(const T& src, T& dst)
{
    if (std::is_trivially_copyable<T>::value) {
        std::cout << "  -> Using fast memcpy-style copy" << std::endl;
    } else {
        std::cout << "  -> Using element-wise copy" << std::endl;
    }
    dst = src;
}

// Compile-time dispatch based on type category
template <typename T>
void describe()
{
    std::cout << "  is_integral      : " << std::is_integral<T>::value << std::endl;
    std::cout << "  is_floating_point: " << std::is_floating_point<T>::value << std::endl;
    std::cout << "  is_arithmetic    : " << std::is_arithmetic<T>::value << std::endl;
    std::cout << "  is_class         : " << std::is_class<T>::value << std::endl;
    std::cout << "  is_pointer       : " << std::is_pointer<T>::value << std::endl;
}

int main()
{
    // ------------------------------------------------------------------
    // 1. Primary type categories
    // ------------------------------------------------------------------
    std::cout << "=== int traits ===" << std::endl;
    describe<int>();
    std::cout << std::endl;

    std::cout << "=== double traits ===" << std::endl;
    describe<double>();
    std::cout << std::endl;

    std::cout << "=== std::string traits ===" << std::endl;
    describe<std::string>();
    std::cout << std::endl;

    // ------------------------------------------------------------------
    // 2. Type properties
    // ------------------------------------------------------------------
    std::cout << "=== Type properties ===" << std::endl;
    std::cout << "  is_const<const int>     : " << std::is_const<const int>::value << std::endl;
    std::cout << "  is_volatile<volatile int>: " << std::is_volatile<volatile int>::value << std::endl;
    std::cout << "  is_signed<int>          : " << std::is_signed<int>::value << std::endl;
    std::cout << "  is_unsigned<unsigned>    : " << std::is_unsigned<unsigned>::value << std::endl;
    std::cout << "  is_empty<std::string>   : " << std::is_empty<std::string>::value << std::endl;
    std::cout << std::endl;

    // ------------------------------------------------------------------
    // 3. Type relationships
    // ------------------------------------------------------------------
    std::cout << "=== Type relationships ===" << std::endl;
    std::cout << "  is_same<int, int>       : " << std::is_same<int, int>::value << std::endl;
    std::cout << "  is_same<int, long>      : " << std::is_same<int, long>::value << std::endl;
    std::cout << "  is_convertible<int,double>: " << std::is_convertible<int, double>::value << std::endl;
    std::cout << std::endl;

    // ------------------------------------------------------------------
    // 4. Type transformations
    // ------------------------------------------------------------------
    typedef std::remove_const<const int>::type NoConstInt;
    typedef std::remove_reference<int&>::type NoRefInt;
    typedef std::add_pointer<int>::type IntPtr;

    std::cout << "=== Type transformations ===" << std::endl;
    std::cout << "  remove_const<const int> is int  : "
              << std::is_same<NoConstInt, int>::value << std::endl;
    std::cout << "  remove_reference<int&> is int   : "
              << std::is_same<NoRefInt, int>::value << std::endl;
    std::cout << "  add_pointer<int> is int*        : "
              << std::is_same<IntPtr, int*>::value << std::endl;
    std::cout << std::endl;

    // ------------------------------------------------------------------
    // 5. Practical use: optimized copy selection
    // ------------------------------------------------------------------
    int a = 42, b = 0;
    std::string s1 = "hello", s2;

    std::cout << "=== Smart copy dispatch ===" << std::endl;
    std::cout << "  Copying int:" << std::endl;
    smartCopy(a, b);
    std::cout << "  Result: " << b << std::endl;

    std::cout << "  Copying string:" << std::endl;
    smartCopy(s1, s2);
    std::cout << "  Result: " << s2 << std::endl;

    return 0;
}

/*
Expected output:

=== int traits ===
  is_integral      : 1
  is_floating_point: 0
  is_arithmetic    : 1
  is_class         : 0
  is_pointer       : 0

=== double traits ===
  is_integral      : 0
  is_floating_point: 1
  is_arithmetic    : 1
  is_class         : 0
  is_pointer       : 0

=== std::string traits ===
  is_integral      : 0
  is_floating_point: 0
  is_arithmetic    : 0
  is_class         : 1
  is_pointer       : 0

=== Type properties ===
  is_const<const int>     : 1
  is_volatile<volatile int>: 1
  is_signed<int>          : 1
  is_unsigned<unsigned>    : 1
  is_empty<std::string>   : 0

=== Type relationships ===
  is_same<int, int>       : 1
  is_same<int, long>      : 0
  is_convertible<int,double>: 1

=== Type transformations ===
  remove_const<const int> is int  : 1
  remove_reference<int&> is int   : 1
  add_pointer<int> is int*        : 1

=== Smart copy dispatch ===
  Copying int:
  -> Using fast memcpy-style copy
  Result: 42
  Copying string:
  -> Using element-wise copy
  Result: hello
*/
Run command
g++ -std=c++11 -Wall -Wextra -o example type_traits.cpp