CodeNebula
C++11stlintermediate

std::type_index (C++11 Addition)

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

Explanation

A copyable, hashable wrapper around `std::type_info` that can be used as a key in associative and unordered containers for runtime type identification.

Real-World Scenario

Build a type-based factory or service locator that maps type identifiers to creation functions.

Quick Snippet

snippet.cpp
#include <typeindex>
#include <unordered_map>
#include <string>
std::unordered_map<std::type_index, std::string> typeNames;
typeNames[std::type_index(typeid(int))] = "int";
typeNames[std::type_index(typeid(double))] = "double";

Full Example

type_index.cpp
// CodeNebula - C++11 Example: std::type_index
// Compile: g++ -std=c++11 -Wall -Wextra -o example type_index.cpp

// std::type_index is a wrapper around std::type_info that can be used
// as a key in associative containers. Unlike type_info, type_index
// is copyable and supports comparison and hashing.

#include <iostream>
#include <typeindex>
#include <typeinfo>
#include <map>
#include <unordered_map>
#include <string>
#include <memory>

// A simple type registry / factory pattern
class Animal {
public:
    virtual ~Animal() = default;
    virtual std::string speak() const = 0;
};

class Dog : public Animal {
public:
    std::string speak() const override { return "Woof!"; }
};

class Cat : public Animal {
public:
    std::string speak() const override { return "Meow!"; }
};

class Bird : public Animal {
public:
    std::string speak() const override { return "Tweet!"; }
};

int main() {
    // type_index from typeid
    std::type_index ti_int = typeid(int);
    std::type_index ti_double = typeid(double);
    std::type_index ti_string = typeid(std::string);

    std::cout << "type_index names:" << std::endl;
    std::cout << "  int:    " << ti_int.name() << std::endl;
    std::cout << "  double: " << ti_double.name() << std::endl;
    std::cout << "  string: " << ti_string.name() << std::endl;

    // Use as map key -- store type metadata
    std::map<std::type_index, std::string> type_names;
    type_names[typeid(int)] = "integer";
    type_names[typeid(double)] = "double";
    type_names[typeid(std::string)] = "string";
    type_names[typeid(Dog)] = "Dog";
    type_names[typeid(Cat)] = "Cat";

    std::cout << "\nType registry (ordered map):" << std::endl;
    for (const auto& kv : type_names) {
        std::cout << "  " << kv.first.name() << " -> " << kv.second << std::endl;
    }

    // Use in unordered_map (type_index has std::hash specialization)
    std::unordered_map<std::type_index, std::string> sounds;
    sounds[typeid(Dog)] = "Woof";
    sounds[typeid(Cat)] = "Meow";
    sounds[typeid(Bird)] = "Tweet";

    // Lookup by runtime type
    std::unique_ptr<Animal> pet = std::make_unique<Cat>();
    auto it = sounds.find(typeid(*pet));
    if (it != sounds.end()) {
        std::cout << "\nRuntime type lookup: " << it->second << std::endl;
    }

    // Comparison operators
    std::type_index a = typeid(int);
    std::type_index b = typeid(int);
    std::type_index c = typeid(double);
    std::cout << "\nComparisons:" << std::endl;
    std::cout << "  int == int:    " << (a == b ? "true" : "false") << std::endl;
    std::cout << "  int == double: " << (a == c ? "true" : "false") << std::endl;
    std::cout << "  int != double: " << (a != c ? "true" : "false") << std::endl;

    // Hash values
    std::cout << "\nHash values:" << std::endl;
    std::cout << "  hash(int):    " << std::type_index(typeid(int)).hash_code() << std::endl;
    std::cout << "  hash(double): " << std::type_index(typeid(double)).hash_code() << std::endl;

    return 0;
}

// Expected output (mangled names vary by compiler):
// type_index names:
//   int:    i
//   double: d
//   string: NSt7...
//
// Type registry (ordered map):
//   ... -> integer
//   ... -> double
//   ... -> string
//   ... -> Dog
//   ... -> Cat
//
// Runtime type lookup: Meow
//
// Comparisons:
//   int == int:    true
//   int == double: false
//   int != double: true
//
// Hash values:
//   hash(int):    <some hash>
//   hash(double): <some hash>
Run command
g++ -std=c++11 -Wall -Wextra -o example type_index.cpp