Templates
Type Traits
Inspect, query, and modify type properties at compile time using the standard type traits library.
Interview: Common in advanced C++ roles. Focuses on SFINAE, std::enable_if, conditional type selection, and checking type relationships at compile time.
Type Traits are template-based compile-time queries that allow you to inspect, verify, and modify the properties of types at compile time. They are defined in the <type_traits> header.
Core Idea
Query properties (like is_pointer or is_integral) of template types to drive conditional code compilation.
Why It Matters
Allows writing optimized generic code (e.g., using std::copy via memcpy for primitive types vs element loops for complex ones).
Interview Lens
Expect design questions involving type dispatching or writing custom enable_if checks to constrain class templates.
Standard Traits Classification
The type traits library contains categories of helpers:
- Primary Categories:
std::is_void,std::is_integral,std::is_floating_point,std::is_pointer,std::is_class. - Type Properties:
std::is_const,std::is_abstract,std::is_polymorphic,std::is_trivially_copyable. - Type Relationships:
std::is_same<T, U>,std::is_base_of<Base, Derived>,std::is_convertible<From, To>. - Type Modifications:
std::remove_const<T>::type,std::decay<T>::type,std::underlying_type<T>::type.
Code Walkthrough
This program demonstrates template constraint checking and tag dispatching via type traits.
#include <iostream> #include <type_traits>// Helper function to print category template <typename T> void process(T val) { if constexpr (std::is_integral_v<T>) { std::cout << "Processing integral: " << val << std::endl; } else if constexpr (std::is_floating_point_v<T>) { std::cout << "Processing floating point: " << val << std::endl; } else { std::cout << "Processing general object" << std::endl; } }
int main() { process(42); // Prints: Processing integral: 42 process(3.14); // Prints: Processing floating point: 3.14 process("hello"); // Prints: Processing general object return 0; }
Interview-Relevant Information
Q: What is SFINAE and how does std::enable_if utilize type traits?
Answer: SFINAE stands for Substitution Failure Is Not An Error. When compiling templates, if substituting a type parameter fails to compile, the compiler simply discards that overload candidate instead of throwing a compiler error. std::enable_if utilizes this by failing type substitution unless a boolean condition (derived from type traits) is true, allowing conditional activation of overloads.
Q: What is the helper suffix _v and _t in type traits?
Answer: Introduced in C++14/C++17, these are template aliases for convenience. Suffix _v extracts the value (e.g. std::is_pointer_v<T> instead of std::is_pointer<T>::value). Suffix _t extracts nested types (e.g. std::remove_const_t<T> instead of typename std::remove_const<T>::type).
Quick Checklist
Can you write an overload constrained by type traits? Do you understand the difference between std::is_same and base relationship checking? If yes, you understand type traits.
Use Cases
Optimizing generic algorithms for primitive arrays using memcpy.
Constraining class template constructors using type-safe constraints.
Common Mistakes
Forgetting std::decay on types when checking equality, leading to checks failing due to reference or const qualifiers.
Using enable_if on return types of constructors (constructors don't have return types; use template parameters instead).