Interview Questions
General Questions
What is the "diamond problem" in C++ and how can it be resolved?
Answer: The "diamond problem" is an ambiguity that arises in C++ when a class inherits from two or more classes that have a common base class. It can be resolved using virtual inheritance, where the common base class is inherited virtually, ensuring only one instance of the base class is present in the derived class hierarchy.
Explain the use of the
const
keyword in C++ with respect to member functions.
Answer: The const
keyword can be used in member function declarations to indicate that the function will not modify the object's data members. It is used for enforcing data member immutability and allowing the function to be called on const
objects.
What is an interface class in C++?
Answer: An interface class in C++ is a class that contains only pure virtual functions and no data members. It defines a contract that derived classes must implement. C++ does not have a specific interface
keyword like some other languages, but this concept is achieved through abstract classes with pure virtual functions.
In this example, the Shape
class is an abstract class serving as an interface. It defines two pure virtual functions, draw()
and area()
, which any class inheriting from Shape
must implement. The Circle
and Rectangle
classes implement these functions, and you can see how they are used polymorphically in the main
function. This demonstrates the use of an interface class in C++ through an abstract class with pure virtual functions.
What is the Rule of Three (Rule of Five) in C++?
Answer: The Rule of Three (prior to C++11) and the Rule of Five (C++11 and later) refer to guidelines for managing resources in classes that involve dynamically allocated memory or other resources. The Rule of Three states that if a class defines a destructor, a copy constructor, or an assignment operator, it should define all three. The Rule of Five extends this concept to include move constructors and move assignment operators.
What is a smart pointer in C++?
Answer: A smart pointer is a C++ object that acts like a pointer but provides automatic memory management, helping to avoid memory leaks. There are three types of smart pointers in C++: std::shared_ptr
, std::unique_ptr
, and std::weak_ptr
.
What is the difference between
std::shared_ptr
andstd::unique_ptr
?
Answer: std::shared_ptr
allows multiple smart pointers to share ownership of a dynamically allocated object, while std::unique_ptr
represents sole ownership of the object and ensures it is deleted when the smart pointer goes out of scope.
Explain the concept of RAII (Resource Acquisition Is Initialization) in C++ and why it's important in OOP.
Answer: RAII is a programming idiom where the acquisition of resources (e.g., memory, files, locks) is tied to the lifetime of an object. It ensures that resources are released when the object goes out of scope or is destroyed. RAII is crucial in OOP to manage resource lifetimes safely and avoid resource leaks.
What is the
virtual
destructor in C++ and when should it be used?
Answer: A virtual
destructor is used when a class is intended to be used as a base class with derived classes. It ensures that the destructor of the most derived class is called when an object is deleted through a pointer to the base class. This is important to prevent resource leaks in polymorphic hierarchies.
What are pure virtual functions and abstract classes, and how are they related?
Answer: A pure virtual function is a virtual function with no implementation in the base class and is declared with = 0
. An abstract class is a class that contains one or more pure virtual functions. Abstract classes cannot be instantiated and serve as a blueprint for derived classes that must implement these pure virtual functions.
What is the difference between
std::vector
andstd::list
in C++ and when would you choose one over the other for storing elements?
Answer:
std::vector
is a dynamic array with contiguous memory, providing efficient random access but potentially expensive insertions/removals.std::list
is a doubly-linked list with efficient insertions/removals but slower random access. Choosestd::vector
for random access andstd::list
for frequent insertions/removals.
Define namespace in C++.
Answer: Namespaces enable us to organize named items that would otherwise have global scope into smaller scopes, allowing us to give them namespace scope. This permits program parts to be organized into distinct logical scopes with names. The namespace provides a place to define or declare identifiers such as variables, methods, and classes.
Or we could say that A namespace is a declarative zone that gives the identifiers (names of types, functions, variables, and so on) within it a scope. Namespaces are used to arrange code into logical categories and to avoid name clashes, which might happen when you have many libraries in your code base.
What is the function of the keyword “Auto”?
Answer: The auto keyword may be used to declare a variable with a complex type in a straightforward fashion. You can use auto to declare a variable if the initialization phrase contains templates, pointers to functions, references to members, etc. With type inference capabilities, we can spend less time having to write out things the compiler already knows. As all the types are deduced in the compiler phase only, the time for compilation increases slightly but it does not affect the runtime of the program.
Define inline function. Can we have a recursive inline function in C++?
Answer: An inline function is a form of request not an order to a compiler which results in the inlining of our function to the main function body. An inline function can become overhead if the execution time of the function is less than the switching time from the caller function to called function. To make a function inline use the keyword inline before and define the function before any calls are made to the function.
The answer is No; It cannot be recursive.
An inline function cannot be recursive because in the case of an inline function the code is merely placed into the position from where it is called and does not maintain a piece of information on the stack which is necessary for recursion.
Plus, if you write an inline keyword in front of a recursive function, the compiler will automatically ignore it because the inline is only taken as a suggestion by the compiler.
- How delete [] is different from delete?
delete[]
delete
It is used for deleting a whole array
It is used to delete only one single pointer
It is used for deleting the objects of new[]; By this, we can say that delete[] is used to delete an array of objects
It is used for deleting the objects of new; By this, we can say that delete is used to delete a single object
It can call as many destructors it wants
It can only call the destructor of a class once
The simple answer is NO we cannot overload a destructor. It is mandatory to only destructor per class in C++. Also to mention, Destructor neither take arguments nor they have a parameter that might help to overload.
When destroying instances or objects of a derived class using a base class pointer object, a virtual destructor is invoked to free up memory space allocated by the derived class object or instance.
Virtual destructor guarantees that first the derived class’ destructor is called. Then the base class’s destructor is called to release the space occupied by both destructors in the inheritance class which saves us from the memory leak. It is advised to make your destructor virtual whenever your class is polymorphic.
Virtual inheritance is a technique that ensures only one copy of a base class’s member variables is inherited by grandchild-derived classes. Or in simple terms, virtual inheritance is used when we are dealing with a situation of multiple inheritances but want to prevent multiple instances of the same class from appearing in the inheritance hierarchy.
- What is the difference between new and malloc()?
new
malloc()
new is an operator which performs an operation
malloc is a function that returns and accepts values
new calls the constructors
malloc cannot call a constructor
new is faster than malloc as it is an operator
malloc is slower than new as it is a function
new returns the exact data type
malloc returns void*
- What is the difference between an array and a list?
Arrays
Lists
Array are contiguous memory locations of homogenous data types stored in a fixed location or size.
Lists are classic individual elements that are linked or connected to each other with the help of pointers and do not have a fixed size.
Arrays are static in nature.
Lists are dynamic in nature
Uses less memory than linked lists.
Uses more memory as it has to store the value and the pointer memory location
- What is the difference between struct and class?
Struct
Class
Members of the struct are always by default public mode
Members of the class can be in private, protected, and public modes.
Structures are of the value type. They only hold value in memory.
Classes are of reference type. It holds a reference of an object in memory.
The memory in structures is stored as stacks
The memory in classes is stored as heaps.
Memory Related Questions
What is memory management in C++?
Answer: Memory management in C++ involves allocating and deallocating memory for variables, objects, and data structures during program execution to efficiently use system resources.
Explain the difference between the stack and the heap in memory allocation.
Answer: The stack is a region of memory used for storing local variables and function call information, and it has a fixed and limited size. The heap is a dynamic memory area used for objects with a potentially longer lifetime, and its size is not fixed.
How is memory allocated on the stack in C++?
Answer: Memory on the stack is automatically allocated when local variables are declared within a function. It is automatically deallocated when the variables go out of scope.
How is memory allocated on the heap in C++?
Answer: Memory on the heap is allocated using dynamic memory allocation functions like
new
andmalloc
. It must be explicitly deallocated usingdelete
orfree
to avoid memory leaks.
Explain the
new
anddelete
operators in C++.Answer:
new
is used to allocate memory for an object on the heap and returns a pointer to the object.delete
is used to deallocate memory previously allocated withnew
.
What is a memory leak in C++? How can you avoid it?
Answer: A memory leak occurs when memory that has been allocated is not deallocated, leading to a gradual consumption of system memory. To avoid memory leaks, always deallocate dynamically allocated memory using
delete
or smart pointers when it is no longer needed.
What are smart pointers in C++? Provide examples of their usage.
Answer: Smart pointers (
std::shared_ptr
,std::unique_ptr
,std::weak_ptr
) are C++ classes that manage the lifetime of dynamically allocated objects. They automatically release memory when it's no longer needed. Here's an example of usingstd::unique_ptr
:
What is stack overflow, and how can it be avoided in C++?
Answer: Stack overflow occurs when the stack runs out of available space due to excessive function calls or large local variables. To avoid it, limit recursion depth, use dynamic memory allocation for large data structures, or increase the stack size (if possible).
Explain the role of the copy constructor and assignment operator in managing memory for user-defined classes.
Answer: The copy constructor and assignment operator are responsible for creating deep copies of objects when they are copied or assigned. Properly implementing these functions is crucial to prevent issues like shallow copies and resource leaks.
Explain all types of pointers ?
Certainly, here's a comprehensive table that includes various types of pointers in C++, including null pointers, dangling pointers, wild pointers, void pointers, and garbage pointers:
Null Pointer
A pointer that does not point to any valid memory location. It represents that a pointer doesn't currently point to anything meaningful.
int* ptr = nullptr;
Dangling Pointer
A pointer that continues to point to a memory location even after the object it points to has been deallocated or has gone out of scope. Accessing a dangling pointer can lead to undefined behavior.
cpp int* ptr; { int x = 10; ptr = &x; } // `ptr` is now a dangling pointer
Wild Pointer
A pointer that is uninitialized, meaning it contains an arbitrary memory address. Accessing a wild pointer can lead to undefined behavior.
cpp int* ptr; *ptr = 42; // Wild pointer access
Garbage Pointer
A pointer that points to a memory location containing unpredictable or arbitrary data, typically due to uninitialized pointers or accessing objects after their lifetime has ended.
cpp int* ptr; int x = *ptr; // Garbage pointer access
Void Pointer
A special pointer type that can point to objects of any type. It's often used for dynamic memory allocation and type casting.
cpp void* ptr = nullptr; int x = 10; ptr = &x;
These various pointer types play different roles in C++ memory management and can have significant implications for program correctness and safety. It's important to understand their characteristics and use them appropriately in your code.
What is ‘this‘ pointer in C++?
Answer : this pointer enables every object to have access to its own address through an essential pointer. All member functions take this pointer as an implicit argument. this pointer may be used to refer to the calling object within a member function.
this pointer is used to pass an object as a parameter to another method.
Each object gets its own copy of the data member.
this pointer is used to declare indexers.
Explain Smart Pointer and their working .
Smart pointers in C++ are objects that manage the lifetime of dynamically allocated memory, providing automatic memory management and helping to prevent common issues like memory leaks. They are part of the C++ Standard Library and come in three main flavors: std::shared_ptr
, std::unique_ptr
, and std::weak_ptr
. Here, I'll explain each type and how they work:
std::shared_ptr:
A
std::shared_ptr
is a smart pointer that allows multiple smart pointers to share ownership of a dynamically allocated object.It keeps track of the number of
std::shared_ptr
instances that share ownership of the object using reference counting.When the last
std::shared_ptr
owning the object goes out of scope or is explicitly reset, the object is deleted, and its memory is freed.
Example:
std::unique_ptr:
A
std::unique_ptr
is a smart pointer that represents sole ownership of a dynamically allocated object.It cannot be shared or copied, making it efficient for cases where ownership transfer is needed.
When a
std::unique_ptr
goes out of scope or is explicitly reset, it deletes the object it owns and frees its memory.
Example:
std::weak_ptr:
A
std::weak_ptr
is a smart pointer that does not affect the ownership of the managed object.It is used to break circular references between
std::shared_ptr
instances and avoid memory leaks.To access the object, you need to create a
std::shared_ptr
from thestd::weak_ptr
(if it still exists).
Example:
Smart pointers in C++ help automate memory management, reduce the risk of resource leaks, and make it easier to write safe and reliable code by ensuring that objects are properly deallocated when they are no longer needed.
Keywords Specific Question
What is the significance of the
auto
keyword in C++11 and later versions?Answer: The
auto
keyword is used for type inference, allowing the compiler to deduce the data type of a variable based on its initializer. It simplifies code by reducing the need for explicit type declarations.
Explain the
const
keyword in C++.Answer: The
const
keyword is used to declare constants or to specify that a variable is read-only and cannot be modified after initialization. It is often used in function declarations to indicate that a function does not modify its parameters.
What does the
static
keyword mean in C++?Answer: The
static
keyword has different meanings depending on its context:When used with variables, it indicates that the variable is shared among all instances of a class (for static class members) or has internal linkage in a translation unit (for global variables).
When used with functions, it restricts the function's scope to the file in which it is defined (internal linkage).
What is the purpose of the
volatile
keyword in C++?Answer: The
volatile
keyword is used to indicate that a variable's value can be changed by external factors not under the program's control, such as hardware or other threads. It prevents the compiler from optimizing away accesses to the variable.
What is the
typename
keyword used for in C++?Answer: The
typename
keyword is often used in templates to specify that a dependent name represents a type. It helps the compiler understand that a name in a template is a type rather than a variable or function.
Explain the
explicit
keyword in C++ and when it is used.Answer: The
explicit
keyword is used in constructor declarations to prevent implicit type conversions during object initialization. It ensures that constructors are only called when explicitly requested, helping avoid unexpected conversions.
What is the
constexpr
keyword, and how is it used in C++11 and later versions?Answer: The
constexpr
keyword is used to indicate that a function or variable can be evaluated at compile-time. It allows for the creation of constant expressions, improving performance and flexibility in some cases.
Describe the role of the
namespace
keyword in C++.Answer: The
namespace
keyword is used to define a named scope for identifiers, helping organize code and avoid naming conflicts. It's commonly used to group related functions, classes, or variables into a logical unit.
What is the purpose of the
operator
keyword in C++?Answer: The
operator
keyword is used to define overloaded operators for user-defined classes. It allows you to specify custom behavior for operators like+
,-
,==
, etc., when applied to objects of your class.
Explain the use of the
delete
anddefault
keywords in C++ for special member functions.Answer: The
delete
keyword is used to explicitly delete a special member function (e.g., constructor, destructor, copy constructor, move constructor, copy assignment operator, move assignment operator), indicating that it should not be used. Thedefault
keyword is used to request the compiler to generate a default implementation of a special member function if it's not explicitly defined.
What is the
friend
keyword used for in C++?Answer: The
friend
keyword is used to grant access to the private and protected members of a class to another class or function. It allows the designated friend to access the private members as if it were a member of the class itself.
Explain the
typeid
keyword and its usage in C++.Answer: The
typeid
keyword is used to determine the actual type of an object at runtime (runtime type identification). It's often used in conjunction with thedynamic_cast
operator to perform type-safe downcasting in polymorphic hierarchies.
What is the
mutable
keyword, and when is it used in C++?Answer: The
mutable
keyword is used to indicate that a data member of a class can be modified even if the member function that accesses it is marked asconst
. This is often used when caching results or maintaining a logical constness.
What are the static data members and static member functions?
Answer : The static data member of a class is a normal data member but preceded with a static keyword. It executes before main() in a program and is initialized to 0 when the first object of the class is created. It is only visible to a defined class but its scope is of a lifetime.
Syntax:
The static member function is the member function that is used to access other static data members or other static member functions. It is also defined with a static keyword. We can access the static member function using the class name or class objects.
Syntax:
What is the main use of the keyword “Volatile”?Just like its name, things can change suddenly and unexpectantly; So it is used to inform the compiler that the value may change anytime. Also, the volatile keyword prevents the compiler from performing optimization on the code. It was intended to be used when interfacing with memory-mapped hardware, signal handlers, and machine code instruction.
- What is a mutable storage class specifier? How can they be used?
Just like its name, the mutable storage class specifier is used only on a class data member to make it modifiable even though the member is part of an object declared as const. Static or const, or reference members cannot use the mutable specifier. When we declare a function as const, this pointer passed to the function becomes const.
- When is void() return type used?
The void keyword, when used as a function return type, indicates that the function does not return a value. When used as a parameter list for a function, void indicates that the function takes no parameters. Non-Value Returning functions are also known as void functions. They’re called “void” since they’re not designed to return anything. True, but only partially. We can’t return values from void functions, but we can certainly return something. Although void functions have no return type, they can return values.
What is the difference between implicit and explicit type casting in C++?
Answer: Implicit type casting, also known as "coercion," is done automatically by the compiler when it is safe and doesn't result in data loss. Explicit type casting, on the other hand, is performed explicitly by the programmer using casting operators like
static_cast
,dynamic_cast
,reinterpret_cast
, andconst_cast
.
Explain the role of the
static_cast
operator in C++ type casting.Answer: The
static_cast
operator is used for safe and reversible type conversions. It performs conversions between related types, such as converting fromint
todouble
or from a base class pointer to a derived class pointer (upcasting).
What is the purpose of the
dynamic_cast
operator in C++ type casting?Answer: The
dynamic_cast
operator is used for dynamic type checking and type-safe downcasting in the context of polymorphic classes (classes with virtual functions). It returns a null pointer or throws an exception if the conversion is not valid.
Explain the use of the
reinterpret_cast
operator in C++ type casting.Answer: The
reinterpret_cast
operator is used for low-level type conversions, such as converting between unrelated pointer types or converting between a pointer and an integer type. It should be used with caution, as it can lead to undefined behavior.
When would you use the
const_cast
operator in C++ type casting, and what does it do?Answer: The
const_cast
operator is used to add or remove theconst
qualifier from a pointer or reference. It allows you to work withconst
and non-const
versions of objects while preserving their values.
Explain the difference between C-style casting (
(type)value
) and C++ casting operators (static_cast
,dynamic_cast
,reinterpret_cast
,const_cast
).Answer: C-style casting is a traditional way of casting, and it can perform a variety of conversions, including dangerous ones. C++ casting operators are safer because they are more specific and provide better type safety. It's generally recommended to use C++ casting operators over C-style casting for better code readability and safety.
What is type narrowing and type widening in type casting?
Answer: Type narrowing refers to converting from a larger data type to a smaller data type, which may result in data loss or truncation. Type widening, on the other hand, is converting from a smaller data type to a larger data type, which usually doesn't result in data loss.
C++ STL Questions
Here are some intermediate to expert-level C++ STL (Standard Template Library) interview questions along with answers:
Question 1: Explain the differences between std::vector
, std::list
, and std::deque
. When would you choose one over the other?
Answer:
std::vector
is a dynamic array with efficient random access but slower insertions/deletions. Use it when you need fast access and few insertions/deletions.std::list
is a doubly-linked list with efficient insertions/deletions but slower access. Use it when you frequently insert or delete elements, and order matters.std::deque
is a double-ended queue with efficient random access, insertions, and deletions at both ends. Use it when you need both random access and efficient insertions/deletions.
Question 2: What is an iterator in C++ STL, and what are the different types of iterators?
Answer: An iterator in C++ STL is an object that allows iterating through elements of a container (e.g., vector, list, map). There are several types of iterators:
Input iterators: Read-only iterators that move forward (e.g.,
const_iterator
).Output iterators: Write-only iterators that move forward (e.g.,
std::back_inserter
).Forward iterators: Read/write iterators that move forward.
Bidirectional iterators: Read/write iterators that move forward and backward (e.g.,
std::list
iterators).Random-access iterators: Read/write iterators that support random access (e.g.,
std::vector
iterators).
Question 3: Explain the purpose and usage of the std::algorithm
library. Give an example.
Answer: The std::algorithm
library provides a collection of functions for common algorithms like sorting, searching, and manipulating containers. It allows developers to perform operations on data structures without needing to implement these algorithms from scratch. For example, you can use std::sort
to sort a vector of integers:
Question 4: What are lambda expressions in C++? How do they work, and when are they useful?
Answer: Lambda expressions are anonymous functions that allow you to define a function in-line. They are useful when you need a small, one-time-use function. Lambda expressions provide more concise and readable code. Example:
Question 5: Explain the purpose of the std::map
and std::unordered_map
containers in C++. When would you choose one over the other?
Answer:
std::map
is an ordered associative container that stores key-value pairs sorted by keys. Use it when you need ordered data and efficient search operations.std::unordered_map
is an unordered associative container that uses hash-based indexing for fast access. Use it when you need fast lookup times, and order doesn't matter.
These intermediate to expert-level C++ STL questions can help evaluate a candidate's proficiency in using the Standard Template Library and their ability to select the appropriate data structures and algorithms for various scenarios.
Question 6: Explain the differences between std::set
, std::unordered_set
, std::multiset
, and std::unordered_multiset
.
Answer:
std::set
is an ordered collection of unique elements. It automatically sorts elements and allows for efficient searches, insertions, and deletions.std::unordered_set
is an unordered collection of unique elements. It uses a hash-based data structure for fast access but does not maintain order.std::multiset
is an ordered collection of elements that allows duplicate values. It automatically sorts elements and supports efficient searches, insertions, and deletions.std::unordered_multiset
is an unordered collection of elements that allows duplicate values. It uses a hash-based data structure for fast access and does not maintain order.
Question 7: What is the difference between std::pair
and std::tuple
in C++ STL? Provide an example of when each would be useful.
Answer:
std::pair
is a container for holding two values of potentially different types. It is often used for simple key-value associations or representing pairs of related data. For example, it can be used to represent coordinates (x, y).std::tuple
is a container for holding multiple values of potentially different types. It is used when you need to bundle together multiple pieces of data, such as in returning multiple values from a function or storing heterogeneous data.
Question 8: Explain what an allocator is in C++ STL and how it is used with containers.
Answer: An allocator in C++ STL is responsible for allocating and deallocating memory for containers, such as vectors and maps. It provides a level of abstraction between the container and the memory management, allowing customization of memory allocation strategies. By default, containers use the default allocator (std::allocator
) provided by the standard library, but custom allocators can be used for specific memory management requirements.
Question 9: What are the benefits and drawbacks of using std::shared_ptr
and std::unique_ptr
for managing dynamic memory in C++?
Answer:
std::shared_ptr
allows multiple shared pointers to own the same resource. It is suitable for scenarios where multiple objects need access to the same resource, and ownership can be shared. However, it introduces overhead due to reference counting and may lead to circular references.std::unique_ptr
represents sole ownership of a resource and provides efficient ownership transfer. It is suitable for scenarios where ownership needs to be strictly exclusive and transferable. It has no reference counting overhead but cannot be shared.
Question 10: Explain the purpose of the std::move
function and how it is used to optimize resource management in C++.
Answer: The std::move
function is used to indicate that a resource can be efficiently moved or transferred from one object to another, typically without copying. It is often used to optimize resource management, such as transferring ownership of dynamic memory or other resources, like file handles. std::move
casts an object to an rvalue reference, enabling move semantics.
Question 11: Explain the purpose of the std::function
class template in C++. Provide an example of its usage.
Answer: std::function
is a polymorphic function wrapper that can store, copy, and invoke callable objects (functions, function pointers, function objects, lambdas, etc.). It provides a way to store functions with different signatures in a uniform way. Here's an example:
Question 12: Explain the purpose of the std::thread
class in C++. How can it be used for concurrent programming?
Answer: std::thread
is a class in C++ that represents a thread of execution. It is used for concurrent programming to execute functions or member functions in separate threads. You can create and launch threads to perform tasks concurrently. Here's an example:
Question 13: What are the advantages of using std::async
and std::future
in C++ for asynchronous programming?
Answer:
std::async
is used to asynchronously execute a function and return astd::future
object that can be used to retrieve the result or check if the operation has completed.std::future
allows you to asynchronously wait for the result of an operation, making it easier to work with concurrent tasks without explicitly managing threads. It provides a mechanism for synchronization and waiting.
Question 14: Explain what a C++ iterator category is and why it is important in the STL.
Answer: In C++, iterators are categorized into different types, each representing a specific set of capabilities and requirements. The iterator categories in C++ are:
Input iterators
Output iterators
Forward iterators
Bidirectional iterators
Random-access iterators
Iterator categories are important because they define the operations that can be performed on iterators and containers. Algorithms in the STL are designed to work with specific iterator categories, ensuring that algorithms are as efficient as possible for various container types.
Question 15: How does the C++ STL handle exceptions during container operations, and what are the best practices for exception handling with STL containers?
Answer:
The C++ STL provides a strong exception guarantee, meaning that if an exception occurs during an operation on a container, the container is left in its original state (no changes are made).
Best practices for exception handling with STL containers include using appropriate algorithms that provide strong exception guarantees (e.g.,
std::vector::push_back
,std::vector::emplace_back
, andstd::vector::insert
). Additionally, consider catching exceptions at an appropriate level in your code to handle them gracefully and avoid data corruption.
Question 16 : STL contianers and how they are implemented ?
Table of C++ containers that includes a column mentioning the data structures typically used in their implementation:
Sequence Containers
Ordered, May Allow Duplicates
std::vector
Dynamic array, fast random access, dynamic resizing.
push_back
, emplace_back
, insert
Dynamic Array
O(n)
O(n)
O(n)
std::deque
Double-ended queue, fast random access, dynamic resizing.
push_back
, push_front
, emplace_back
, emplace_front
, insert
Array of Blocks
O(1) (amortized)
O(1) (amortized)
O(n)
std::list
Doubly-linked list, efficient insertions/deletions, slow random access.
insert
, emplace
, emplace_front
, emplace_back
Doubly-Linked List
O(1)
O(1)
O(n)
std::forward_list
Singly-linked list, efficient insertions/deletions, slow random access.
insert_after
, emplace_after
, push_front
, emplace_front
Singly-Linked List
O(1)
O(1)
O(n)
Associative Containers
Ordered by keys, No Duplicates
std::set
Sorted set of unique keys.
insert
, emplace
Balanced Binary Search Tree (e.g., Red-Black Tree)
O(log n)
O(log n)
O(log n)
std::multiset
Sorted set of keys allowing duplicates.
insert
, emplace
Balanced Binary Search Tree (e.g., Red-Black Tree)
O(log n)
O(log n)
O(log n)
std::map
Sorted key-value pairs, unique keys.
insert
, emplace
, operator[]
Balanced Binary Search Tree (e.g., Red-Black Tree)
O(log n)
O(log n)
O(log n)
std::multimap
Sorted key-value pairs, allowing duplicate keys.
insert
, emplace
Balanced Binary Search Tree (e.g., Red-Black Tree)
O(log n)
O(log n)
O(log n)
Unordered Associative Containers
Hashed, No Duplicates
std::unordered_set
Unordered set of unique keys.
insert
, emplace
Hash Table
O(1) average
O(1) average
O(1) average
std::unordered_multiset
Unordered set of keys allowing duplicates.
insert
, emplace
Hash Table
O(1) average
O(1) average
O(1) average
std::unordered_map
Unordered key-value pairs, unique keys.
insert
, emplace
, operator[]
Hash Table
O(1) average
O(1) average
O(1) average
std::unordered_multimap
Unordered key-value pairs, allowing duplicate keys.
insert
, emplace
Hash Table
O(1) average
O(1) average
O(1) average
Container Adapters
Wrappers around sequence containers
std::stack
LIFO (Last-In-First-Out) behavior, typically implemented using std::deque
.
push
, emplace
, top
Deque
O(1) (amortized)
O(1) (amortized)
-
std::queue
FIFO (First-In-First-Out) behavior, typically implemented using std. deque
.
push
, emplace
, front
, back
Deque
O(1) (amortized)
O(1) (amortized)
-
std::priority_queue
Priority queue, typically implemented using std::vector
.
push
, emplace
, top
Heap
O(log n)
O(log n)
-
Array-like Containers
Fixed Size
std::array
Fixed-size array with type safety and stack allocation.
-
Array
-
-
O(n)
std::bitset
Fixed-size bitset for efficient manipulation of bits.
-
Bitset
-
-
O(1)
Other Containers
Specialized
std::valarray
Container for numerical values with element-wise operations.
-
-
-
-
-
std::complex
Container for complex numbers with arithmetic operations.
-
-
-
-
-
This updated table includes the data structures typically used in the implementation of C++ containers, providing a more comprehensive understanding of how these containers are designed and perform their operations. Please note that the choice of data structure may vary among different C++ library implementations.
Last updated
Was this helpful?