Exception Handling & Templates Interview Questions - C++ Programming
Last Updated :
08 Aug, 2025
In modern C++, writing robust, reusable, and efficient code is key. Two important pillars that support this are:
- Exception Handling: C++ supports a structured error-handling mechanism using:
try: block of code that may throw an exception
throw: used to raise an exception
catch: handles the thrown exception
- Templates: Templates in C++ are a feature that allows you to write generic and reusable code. Instead of writing the same function or class multiple times for different data types (like
int
, float
, double
), you can use templates to create a single blueprint that works for any data type.
1. What happens when a constructor throws an exception in C++? Will the destructor of that object be called?
If a constructor throws an exception, the object is considered not fully constructed, and its destructor is not called. However, destructors of already fully constructed sub-objects or members will be called. This behavior ensures proper resource cleanup during object construction failure.
Example:
C++
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "A Constructor\n"; throw runtime_error("Error in A"); }
~A() { cout << "A Destructor\n"; }
};
class B {
public:
B() { cout << "B Constructor\n"; }
~B() { cout << "B Destructor\n"; }
};
int main() {
try {
B b; // Constructed successfully
A a; // Throws exception
} catch (...) {
cout << "Caught exception\n";
}
return 0;
}
2. What are templates in C++? Explain their importance.
Templates in C++ are a powerful feature that allows the creation of generic functions and classes. Instead of writing multiple versions of a function or class for different data types (e.g., int
, float
, double
), templates let you write a single version that works for any type. Templates increase code reusability, reduce duplication, and are type-safe. They are widely used in the Standard Template Library (STL) for generic data structures like vector
, stack
, etc.
Example:
C++
template <typename T>
T add(T a, T b) {
return a + b;
}
This function works for int
, float
, and other types that support the +
operator.
3. What are standard exceptions in C++? List some common types.
C++ provides a hierarchy of standard exceptions in the <exception>
and <stdexcept>
headers. These are predefined classes derived from the base class std::exception
and can be used to represent common errors.
Some commonly used standard exceptions:
std::exception
– Base class for all exceptionsstd::bad_alloc
– Thrown when memory allocation fails (new
)std::out_of_range
– For invalid array or container indexingstd::runtime_error
– Represents errors at runtimestd::invalid_argument
– For invalid function argumentsstd::length_error
, std::overflow_error
, etc.
Example:
C++
#include <stdexcept>
throw std::out_of_range("Index is out of range");
Using standard exceptions makes your code consistent and compatible with STL and third-party libraries.
4. How do you create a custom exception in C++? Give an example.
You can create a custom exception by defining a class that inherits from the std::exception
class and overriding its what()
method, which returns an error message.
Example:
C++
#include <iostream>
#include <exception>
using namespace std;
class MyException : public exception {
public:
const char* what() const noexcept override {
return "Custom Exception Occurred";
}
};
int main() {
try {
throw MyException();
} catch (const MyException& e) {
cout << e.what();
}
}
Benefits:
- Provides clear error information
- Works seamlessly with standard exception handling
- Encourages structured and maintainable code
5. What is a function template in C++? Write a simple example.
A function template allows a function to operate on generic data types. It provides a way to write one function for multiple types, which is resolved at compile-time.
Syntax:
C++
template <typename T>
T maxVal(T a, T b) {
return (a > b) ? a : b;
}
6. What is RAII in C++ and how does it relate to exception safety?
RAII (Resource Acquisition Is Initialization) is a design pattern where resources (like memory, file handles, sockets) are acquired in the constructor of an object and released in its destructor. RAII ensures automatic cleanup, even if an exception is thrown, making code exception-safe.
Example:
C++
class FileHandler {
ifstream file;
public:
FileHandler(string filename) {
file.open(filename);
}
~FileHandler() {
file.close(); // Automatically called
}
};
In this example, even if an error occurs, the file is properly closed when the object goes out of scope.
7. What is the use of the catch(...)
block? How is it different from specific catch blocks?
The catch(...)
block is used to catch any type of exception, regardless of its data type or class. It acts as a generic fallback handler.
Example:
C++
try {
throw 3.14; // double type
} catch (...) {
cout << "Caught an unknown exception.";
}
Difference:
catch(int e)
: catches only int
exceptionscatch(...)
: catches all exceptions, even if no matching type is found
It’s helpful when you want to ensure that no exception escapes unhandled, but it does not provide specific details about the exception type.
8. What is the difference between inline
and constexpr
in C++?
Feature | inline | constexpr |
---|
Purpose | Suggests the compiler to replace function | Ensures compile-time evaluation |
Return type | Any | Must return a value known at compile time |
C++ Version | Available since C++98 | Introduced in C++11 (improved in C++14/17/20) |
Example constexpr
:
C++
constexpr int square(int x) {
return x * x;
}
int arr[square(3)]; // Valid at compile time
Example inline
:
C++
inline int cube(int x) {
return x * x * x;
}
Use constexpr
when the value is needed at compile-time, and inline
when you want faster execution without function call overhead.
9. Can we catch a derived exception in a base catch block? What are the risks involved?
Yes, C++ allows catching derived exceptions using a base class reference (std::exception &). But object slicing or loss of specific information can occur if exceptions are not caught by reference or pointer.
Example:
C++
#include <iostream>
#include <stdexcept>
using namespace std;
class MyException : public runtime_error {
public:
MyException(const string& msg) : runtime_error(msg) {}
};
int main() {
try {
throw MyException("Custom error occurred");
} catch (const exception& e) {
cout << "Caught: " << e.what() << endl;
}
}
10. What happens if an exception is thrown but not caught?
If an exception is thrown but not caught by any catch
block, the program invokes the std::terminate()
function, which by default aborts the program.
Example:
C++
void func() {
throw 10; // no catch block here
}
int main() {
func(); // Unhandled exception
}
Output:
terminate called after throwing an instance of 'int'
Aborted (core dumped)
This can lead to abrupt termination, loss of data, or unclean resource release. That's why it's critical to ensure every throw has a matching catch, either directly or through stack unwinding.
11. What is stack unwinding in exception handling? Explain its role.
Stack unwinding is the process of cleaning up the function call stack after an exception is thrown and before it is caught. It ensures that destructors of all local objects are called properly in the reverse order of their creation.
Why is it important?
- Prevents memory/resource leaks
- Ensures safe destruction of objects
- Supports RAII (Resource Acquisition Is Initialization)
Example:
C++
#include<iostream>
using namespace std;
class Demo {
public:
Demo() { cout << "Constructor\n"; }
~Demo() { cout << "Destructor\n"; }
};
void test() {
Demo d;
throw 1; // Stack unwinding will destroy d
}
int main() {
try {
test();
} catch (...) {
cout << "Exception caught\n";
}
}
Output:
Constructor
Destructor
Exception caught
This shows that even when an exception occurs, destructors are called properly to clean up resources.
12. What is the difference between throw;
and throw ex;
inside a catch block?
throw;
– Re-throws the current exception (must be used inside a catch block).throw ex;
– Throws a copy of the exception ex
.
Example:
C++
try {
throw runtime_error("Error");
} catch (runtime_error& e) {
cout << "Handling exception...\n";
throw; // re-throws same exception
}
throw; preserves the original exception type and stack trace, which is important for advanced debugging and exception chaining.
13. What is the use of noexcept
in C++ exception handling?
The noexcept
keyword is used to indicate that a function will not throw an exception. It helps the compiler with optimizations and improves program clarity.
Example:
C++
void display() noexcept {
cout << "This function won't throw";
}
Benefits:
- Faster execution (compiler skips setting up exception-handling code)
- Clear documentation of function behavior
- Can cause
std::terminate()
if the function throws anyway
noexcept
is especially important in move constructors and destructors in modern C++.
14. What will happen if you throw an exception from a destructor?
Throwing an exception from a destructor during stack unwinding (i.e., while handling another exception) results in a call to std::terminate(), which aborts the program.
Example:
C++
class Test {
public:
~Test() {
cout << "Destructor called\n";
throw runtime_error("Error in destructor");
}
};
int main() {
try {
Test t;
throw logic_error("Main exception");
} catch (...) {
cout << "Caught in main\n";
}
}
Avoid throwing from destructors, especially when exceptions are active. Use std::uncaught_exceptions() (C++17) or try-catch inside destructor to suppress.
15. Can function templates be partially specialized in C++? If not, what is the alternative?
Function templates cannot be partially specialized, only fully specialized. To achieve behavior similar to partial specialization, function overloading or tag dispatching with structs is used.
Example (Alternative using enable_if):
C++
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
typename enable_if<is_integral<T>::value>::type
func(T x) {
cout << "Integral version: " << x << endl;
}
template<typename T>
typename enable_if<is_floating_point<T>::value>::type
func(T x) {
cout << "Floating point version: " << x << endl;
}
int main() {
func(10); // int
func(3.14); // double
}
Using std::enable_if, we mimic specialization behavior for functions based on type traits, allowing cleaner and type-specific implementations.
16. What happens when you throw a pointer vs. throw an object in C++?
Throwing a pointer means you're throwing an address. It won’t trigger automatic destruction of the object pointed to, and catching it requires catching the same pointer type. Throwing by value creates a copy, and cleanup is automatic.
Example:
C++
#include <iostream>
using namespace std;
class X {
public:
X() { cout << "X constructed\n"; }
~X() { cout << "X destroyed\n"; }
};
int main() {
try {
X* ptr = new X();
throw ptr; // throw pointer, not object
} catch (X* e) {
cout << "Caught pointer to X\n";
delete e; // manual cleanup required
}
}
Throwing objects ensures RAII and automatic cleanup. Throwing pointers must be handled with care to avoid memory leaks.
17. Can a function template throw an exception based on the type it is instantiated with?
Yes. Templates can use static_assert or if constexpr to control logic at compile-time based on type, and can throw exceptions conditionally at runtime.
Example:
C++
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
void check(T val) {
if constexpr (is_same<T, int>::value) {
if (val < 0) throw runtime_error("Negative int not allowed");
}
cout << "Value is: " << val << endl;
}
int main() {
try {
check(10); // OK
check(-5); // Throws
} catch (exception& e) {
cout << "Caught: " << e.what() << endl;
}
}
Templates can adapt behavior based on type at compile time. Combining this with runtime exception logic adds powerful type-aware safety mechanisms.
Similar Reads
User-defined Custom Exception with class in C++ We can use Exception handling with class too. Even we can throw an exception of user defined class types. For throwing an exception of say demo class type within try block we may write throw demo(); Example 1: Program to implement exception handling with single class CPP14 #include <iostream>
3 min read
Templates in C++ C++ template is a powerful tool that allows you to write a generic code that can work with any data type. The idea is to simply pass the data type as a parameter so that we don't need to write the same code for different data types.For example, some sorting algorithm can work for different type, so
8 min read
Stack Unwinding in C++ Stack Unwinding is the process of removing function call frames from function call stack at run time. The local objects are destroyed in reverse order in which they were constructed.Stack unwinding is a normal process that occurs when a function returns a value. But it can also occur due to exceptio
4 min read
Function Overloading vs Function Templates in C++ In C++, both function overloading and function templates allow us to create functions that can operate on different types of data. While they might seem similar, they are used for different purposes. In this article, we will learn the differences between function overloading and function templates,
4 min read
Exception Handling using Classes in C++ In C++, unexpected issues may occur during program execution such as attempting to divide by zero, accessing a non-existent file or using invalid data. These issues are called exceptions. These exceptions must be handled to avoid abnormal termination of the program.C++ provides try-catch block to ha
5 min read
How to Throw an Exception in C++? In C++, exception handling is a mechanism that allows us to handle runtime errors and exceptions are objects that represent an error that occurs during the execution of a program. In this article, we will learn how to throw an exception in C++. Throw a C++ ExceptionThrowing an exception means sendin
2 min read