New Age C++

C++ Introspection

C++ has several methods -- including the <type_traits> header and runtime type information -- to help your application make type-based decisions.

C++ programmers, unlike Java and .NET developers, don't get the benefit of runtime introspection -- the ability to learn about a class's features. However, C++ offers some limited introspection at both compile time and runtime that are worth examining.

The <type_traits> Header
I'll start with compile time. C++11 added a header, <type_traits>, with functions that can ask aspects about a type. This makes sense with template programming (and meta-programming as well), because you're working with generic types; but you still want to make sure the types meet certain premises.

<type_traits> is less granular than Java and .NET introspection APIs, because it doesn't allow you to extract class information via reflection (like method names or its parameters). Its functions help determine things like whether a type is C-compatible (plain-old data), or a class, function, reference, void and so on. Here are a few examples of <type_traits>:

// #include <type_traits>
is_pod<my_type>::value // The expression is true if my_type is a plain
                       // old data type compatible with C
is_array<my_array>::value // True if my_array is a primitive array

is_abstract<my_type>::value // True if my_type declares or inherits
                            // pure virtual functions
is_base_of<my_type_1, my_type_2> // True if my_type_2 derives from
                                 // my_type_1
<type_traits> also helps determine if a type supports certain operators like the default constructor, copy and move assignments, and so on:
is_default_constructible<my_type>::value // The expression is true if
                                         // my_type has an accessible default constructor
is_move_assignable<my_type> // True if my_type has an accessible move
                            // assignment operator
is_destructible<my_type> // True if my_type has a non-deleted destructor
Compile-time assertion checking is a great complement to the functions included in <type_traits>. This is probably why they came together in C++11. The reserved keyword static_assert evaluates a constant expression, usually based on <type_traits> functions (although this isn't mandatory). If the expression is false, a compile error is issued:
static_assert(has_virtual_destructor<my_type>::value,
  "my_type needs a virtual destructor for derived classes to be safely deleted.");

Compile-Time Type Inference
The C++ equivalent of the C# keyword var is auto. This reserved word existed previously, but it was repurposed in C++11. Before, it meant automatic storage duration. In practice, an automatic variable is allocated at the beginning of the enclosing block in which it's declared, and de-allocated at the end. With C++11, a variable declared as auto means to declare that the variable is the type of the expression used to initialize it. In other words, an automatic variable must be initialized or a compile error will be produced:

auto i = 0; // i is int
This keyword is extremely practical, even in cases when you don't need to infer a type, and you just want to avoid typing it:
list<string> hello_list {"hello", "world"};
auto hello_iter = begin(hello_list); // hello_iter type is list<string>::iterator
Auto comes with a complementary new keyword -- decltype -- that declares a variable by inferring its type, but without getting it initialized:
template<class T, class U>
auto add(T t, U u) -> decltype(t + u) // The return type of add is the type of operator+(T,U)
{
  return t + u;
}
// add(1, 1.2) type is double
That covers compile-time introspection. What about runtime?

Runtime Type Information
Runtime introspection, curiously, was around before C++11. Like <type_traits>, it's limited to type names, not class members. Rather than generic programming, runtime type information (RTTI) is useful in polymorphic scenarios when you need to know what type of hierarchy is being pointed to or referred:

// #include <typeinfo>
auto my_array = { "Hello,", "world!" }; // std::initializer_list<char*>
cout << "The type of my_array is " << typeid(my_array).name() << '\n';

Make C++ Types Speak by Themselves
The principle of object orientation is all about abstraction. Consequently, algorithms that act on types should defer to these types to deal with their internals in their way. However, this might be sometimes unavoidable. In generic programming, for instance, you may need to keep some control over the kind of specialization made on a template. The functions declared in the <type_traits> header, especially when combined with static assertions, are effective tools you can use to make decisions at compile time. Likewise, when you need to know the actual type referred to by a pointer or reference, RTTI can assist you.

This level of introspection doesn't equal what you get with managed code, but it can certainly help your application make decisions based on actual instantiated types.

About the Author

Diego Dagum is a software architect and developer with more than 20 years of experience. He can be reached at [email protected].

comments powered by Disqus

Featured

  • .NET 11 Preview 5 Focuses on Performance, Productivity and Safer Code

    .NET 11 Preview 5 focuses on under-the-hood runtime performance gains, streamlined APIs and language features that reduce boilerplate, plus built‑in security checks and incremental ASP.NET Core and EF Core improvements aimed at everyday developer productivity.

  • VS Code 1.124 Focuses on Agent Autonomy and Parallel Sessions

    Microsoft's June 2026 VS Code update turns on Autopilot by default and adds background sending for agent sessions.

  • Developing Agentic Systems in .NET: From Concept to Code

    ZioNet founder Alon Fliess previews his Visual Studio Live! San Diego session on building true agentic systems in .NET -- covering the cognitive loop, MCP tool integration, multi-agent orchestration and enterprise hosting and governance with the Microsoft Agent Framework.

  • Mastering AI Development and Building AI Apps with GitHub Copilot

    Two Microsoft experts explain how GitHub Copilot is evolving from a coding assistant into a broader platform for building, customizing and testing AI-powered developer workflows.

Subscribe on YouTube