C++ Function Quiz
40 in-depth questions covering C++ function fundamentals including declaration, parameters, overloading, passing mechanisms, and inline functions — with 10 code examples to solidify understanding.
Question 1
When designing a function that must modify its input parameters and return multiple values, what parameter passing mechanism provides the most efficient and clear implementation?
#include <iostream>
void processData(int& input, int& output1, int& output2) {
input *= 2; // Modify input
output1 = input + 10;
output2 = input * 3;
}
int main() {
int value = 5, result1, result2;
processData(value, result1, result2);
std::cout << value << " " << result1 << " " << result2;
return 0;
}Question 2
In a function that performs complex calculations on large objects, what return mechanism avoids unnecessary copying while maintaining type safety?
#include <vector>
#include <iostream>
std::vector<int> createLargeVector() {
std::vector<int> result;
for(int i = 0; i < 1000000; ++i) {
result.push_back(i);
}
return result; // Move semantics avoid copying
}
int main() {
auto vec = createLargeVector(); // Efficient move, not copy
std::cout << vec.size();
return 0;
}Question 3
When implementing overloaded functions that handle different numeric types with similar logic, what design approach provides the most maintainable and extensible code?
#include <iostream>
// Function template for any arithmetic type
template<typename T>
T calculate(T a, T b) {
return (a + b) * 2;
}
// Specialization for int
int calculate(int a, int b) {
return (a + b) * 2 + 1; // Special logic for integers
}
int main() {
std::cout << calculate(3.5, 2.1) << " "; // Uses template
std::cout << calculate(3, 2); // Uses specialization
return 0;
}Question 4
In a performance-critical function that is called frequently with small data, what inline directive provides the best balance between performance and code size?
#include <iostream>
inline int fastMultiply(int a, int b) {
return a * b; // Simple operation, good for inlining
}
int main() {
int result = 0;
for(int i = 0; i < 1000000; ++i) {
result += fastMultiply(i, 2); // May be inlined
}
std::cout << result;
return 0;
}Question 5
When designing a function that must work with both const and non-const objects, what overloading pattern provides the most intuitive interface?
#include <iostream>
#include <vector>
class Container {
std::vector<int> data;
public:
// Const version for reading
const int& get(size_t index) const {
return data[index];
}
// Non-const version for modification
int& get(size_t index) {
return data[index];
}
};
int main() {
Container c;
const Container& constRef = c;
constRef.get(0); // Calls const version
c.get(0); // Calls non-const version
return 0;
}Question 6
Consider this function overloading scenario. Which function will be called when we invoke add(5, 3.14)?
#include <iostream>
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int main() {
auto result = add(5, 3.14);
return 0;
}Question 7
In a function that processes a large container by reference to avoid copying, what const qualification provides the most safety and flexibility?
#include <vector>
#include <iostream>
void printSize(const std::vector<int>& container) {
std::cout << container.size(); // Can read, not modify
}
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
printSize(vec); // Efficient, no copy
return 0;
}Question 8
When implementing a function that must return a reference to an internal static object, what considerations affect the design and safety?
#include <iostream>
#include <string>
const std::string& getDefaultName() {
static std::string defaultName = "Default"; // Static lifetime
return defaultName; // Safe to return reference
}
int main() {
const std::string& name = getDefaultName(); // Valid reference
std::cout << name;
return 0;
}Question 9
In a function template that must handle both lvalue and rvalue arguments efficiently, what parameter type provides the most flexible and optimized implementation?
#include <iostream>
#include <vector>
// Universal reference template
function template<typename T>
void process(T&& arg) {
std::cout << "Processing: " << arg << std::endl;
}
int main() {
int x = 42;
process(x); // lvalue reference
process(42); // rvalue reference
process(std::move(x)); // rvalue reference
return 0;
}Question 10
When designing overloaded operators as functions, what naming convention and parameter patterns provide the most intuitive usage?
#include <iostream>
class Complex {
double real, imag;
public:
Complex(double r, double i) : real(r), imag(i) {}
// Member operator for asymmetric operations
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
};
// Global operator for symmetric operations
Complex operator*(const Complex& a, const Complex& b) {
return Complex(a.real * b.real - a.imag * b.imag,
a.real * b.imag + a.imag * b.real);
}
int main() {
Complex c1(1, 2), c2(3, 4);
auto sum = c1 + c2; // Member operator
auto prod = c1 * c2; // Global operator
return 0;
}Question 11
In a recursive function that processes tree structures, what parameter passing mechanism prevents unnecessary copying while maintaining safety?
#include <iostream>
struct Node {
int value;
Node* left;
Node* right;
};
int sumTree(const Node* node) { // Const pointer prevents modification
if (!node) return 0;
return node->value + sumTree(node->left) + sumTree(node->right);
}
int main() {
// Tree structure would be built here
return 0;
}Question 12
When implementing a function that must handle variable numbers of arguments, what modern C++ feature provides the most type-safe and flexible solution?
#include <iostream>
// Variadic template function
template<typename... Args>
void printAll(Args... args) {
// Fold expression for printing
(std::cout << ... << args) << std::endl;
}
int main() {
printAll(1, " ", 3.14, " ", "hello"); // Any number of arguments
return 0;
}Question 13
In a function that performs computation on fundamental types, what inline specification provides the best performance characteristics?
#include <iostream>
inline double fastSqrt(double x) {
// Complex mathematical computation
double result = x;
for(int i = 0; i < 10; ++i) {
result = 0.5 * (result + x / result);
}
return result;
}
int main() {
double val = fastSqrt(16.0); // May or may not be inlined
std::cout << val;
return 0;
}Question 14
When designing a function that must return different types based on input parameters, what language feature provides the most elegant solution?
#include <iostream>
#include <type_traits>
// Function template with auto return type deduction
auto process(int x) {
if (x > 0) return x * 2; // Returns int
else return x * 2.0; // Returns double
}
int main() {
auto result1 = process(5); // int
auto result2 = process(-3); // double
return 0;
}Question 15
In a function that modifies a container through a reference parameter, what const considerations affect the interface design?
#include <vector>
#include <iostream>
void addElement(std::vector<int>& container) { // Non-const reference
container.push_back(42); // Modifies container
}
void printSize(const std::vector<int>& container) { // Const reference
std::cout << container.size(); // Only reads
}
int main() {
std::vector<int> vec;
addElement(vec); // Can modify
printSize(vec); // Can only read
return 0;
}Question 16
Consider this function with default parameters. What happens when we call print(10)?
#include <iostream>
void print(int x, int y = 20, int z = 30) {
std::cout << x << " " << y << " " << z << std::endl;
}
int main() {
print(10);
return 0;
}Question 17
When implementing a function that must handle both success and error cases, what return type pattern provides the most expressive error handling?
#include <iostream>
#include <optional>
std::optional<int> safeDivide(int a, int b) {
if (b == 0) return std::nullopt; // Error case
return a / b; // Success case
}
int main() {
auto result = safeDivide(10, 2);
if (result) {
std::cout << *result; // 5
} else {
std::cout << "Division by zero";
}
return 0;
}Question 18
In a function template that must constrain its parameters to specific types, what C++ feature provides the most readable and maintainable constraints?
#include <iostream>
#include <concepts>
// Function template with concepts
template<typename T>
requires std::integral<T> // Only integral types
T factorial(T n) {
T result = 1;
for(T i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
int main() {
std::cout << factorial(5); // Works
// factorial(3.14); // Would fail to compile
return 0;
}Question 19
When designing a function that must be callable from C code, what declaration attributes ensure C linkage and calling convention compatibility?
#include <iostream>
// C-compatible function
extern "C" int cFunction(int x) {
return x * 2;
}
// Regular C++ function
int cppFunction(int x) {
return x * 3;
}
int main() {
std::cout << cFunction(5) << " " << cppFunction(5);
return 0;
}Question 20
In a performance-critical mathematical function that is called in tight loops, what combination of features provides the best optimization opportunities?
#include <iostream>
// Constexpr for compile-time evaluation when possible
constexpr double fastPower(double base, int exp) {
double result = 1.0;
for(int i = 0; i < exp; ++i) {
result *= base;
}
return result;
}
int main() {
constexpr double compileTime = fastPower(2.0, 3); // Compile-time
double runtime = fastPower(2.0, 3); // Runtime
std::cout << compileTime << " " << runtime;
return 0;
}Question 21
When implementing overloaded functions for a math library that must handle different precision levels, what design pattern provides the most intuitive user experience?
#include <iostream>
#include <cmath>
// Overloaded functions for different precisions
double sin(double x) { return std::sin(x); }
float sin(float x) { return std::sinf(x); }
long double sin(long double x) { return std::sinl(x); }
int main() {
double d = sin(1.0); // Calls double version
float f = sin(1.0f); // Calls float version
std::cout << d << " " << f;
return 0;
}Question 22
In a function that processes a string by reference to avoid copying, what parameter type provides the most flexible and safe interface?
#include <iostream>
#include <string>
void processString(const std::string& str) {
std::cout << "Length: " << str.length() << std::endl;
// Cannot modify str here
}
int main() {
std::string s = "Hello World";
processString(s); // lvalue
processString("temp"); // rvalue
return 0;
}Question 23
When designing a function that must handle both mutable and immutable data structures, what overloading strategy provides the most comprehensive interface?
#include <iostream>
#include <vector>
class DataProcessor {
std::vector<int> data;
public:
// Const version for read-only access
int getSum() const {
int sum = 0;
for(int val : data) sum += val;
return sum;
}
// Non-const version for modification
void addValue(int val) {
data.push_back(val);
}
};
int main() {
DataProcessor dp;
dp.addValue(5); // Non-const call
const DataProcessor& cdp = dp;
std::cout << cdp.getSum(); // Const call
return 0;
}Question 24
In a function template that must handle containers of different types, what template parameter pattern provides the most flexible container access?
#include <iostream>
#include <vector>
#include <list>
// Template function for any container type
template<typename Container>
void printElements(const Container& container) {
for(const auto& element : container) {
std::cout << element << " ";
}
std::cout << std::endl;
}
int main() {
std::vector<int> vec = {1, 2, 3};
std::list<double> lst = {1.1, 2.2, 3.3};
printElements(vec); // Works with vector
printElements(lst); // Works with list
return 0;
}Question 25
When implementing a function that must return a newly created object, what return mechanism provides the most efficient transfer of ownership?
#include <iostream>
#include <vector>
std::vector<int> createVector(int size) {
std::vector<int> result;
result.reserve(size);
for(int i = 0; i < size; ++i) {
result.push_back(i * 2);
}
return result; // Move semantics transfer ownership
}
int main() {
auto vec = createVector(1000000); // Efficient move, not copy
std::cout << vec.size();
return 0;
}Question 26
In a function that performs validation on input parameters, what early return pattern provides the most readable and maintainable error handling?
#include <iostream>
#include <stdexcept>
int divide(int a, int b) {
if (b == 0) {
throw std::invalid_argument("Division by zero");
}
return a / b;
}
// Or with early return:
int safeDivide(int a, int b) {
if (b == 0) return 0; // Early return on error
return a / b;
}
int main() {
try {
std::cout << divide(10, 0);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what();
}
return 0;
}Question 27
When designing overloaded operators for a user-defined type, what implementation approach provides the most consistent and expected behavior?
#include <iostream>
class Point {
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
// Member operator for asymmetric operations
Point& operator+=(const Point& other) {
x += other.x;
y += other.y;
return *this;
}
};
// Global operator using member operator
Point operator+(Point lhs, const Point& rhs) {
lhs += rhs;
return lhs;
}
int main() {
Point p1(1, 2), p2(3, 4);
Point sum = p1 + p2; // Uses global operator
return 0;
}Question 28
In a recursive function that processes hierarchical data, what parameter design prevents stack overflow while maintaining efficiency?
#include <iostream>
struct TreeNode {
int value;
TreeNode* left;
TreeNode* right;
};
// Efficient recursive function
int sumTree(const TreeNode* node) {
if (!node) return 0;
return node->value +
sumTree(node->left) +
sumTree(node->right);
}
int main() {
// Tree would be constructed here
return 0;
}Question 29
When implementing a function that must handle both fundamental types and user-defined types efficiently, what template design provides the most optimized code generation?
#include <iostream>
// Template with specialization
template<typename T>
T process(T value) {
return value * 2; // General case
}
// Specialization for int
template<>
int process(int value) {
return value * 2 + 1; // Special logic for int
}
int main() {
std::cout << process(3.5) << " "; // Uses general template
std::cout << process(3); // Uses specialization
return 0;
}Question 30
In a function that must maintain state between calls without global variables, what design pattern provides the most encapsulated and thread-safe solution?
#include <iostream>
int counter() {
static int count = 0; // Static local variable
return ++count;
}
int main() {
std::cout << counter() << " "; // 1
std::cout << counter() << " "; // 2
std::cout << counter(); // 3
return 0;
}Question 31
When designing a function that must handle variable argument counts with type safety, what C++ feature provides the most robust implementation?
#include <iostream>
// Variadic template with fold expression
template<typename... Args>
auto sum(Args... args) {
return (args + ...); // Fold expression
}
int main() {
std::cout << sum(1, 2, 3, 4, 5); // Any number of int args
return 0;
}Question 32
Consider this inline function definition. What happens when this code is compiled and the function is called?
#include <iostream>
inline int square(int x) {
return x * x;
}
int main() {
int result = square(5);
std::cout << result;
return 0;
}Question 33
In a function that must return a reference to one of its parameters based on a condition, what reference qualification ensures lifetime safety?
#include <iostream>
#include <string>
// Function returning reference to parameter
const std::string& longerString(const std::string& a, const std::string& b) {
return a.length() > b.length() ? a : b;
}
int main() {
std::string s1 = "short", s2 = "much longer string";
const std::string& result = longerString(s1, s2);
std::cout << result; // Safe reference to s2
return 0;
}Question 34
When implementing a function template that must handle both copyable and movable types efficiently, what parameter type provides the most optimized implementation?
#include <iostream>
#include <vector>
// Universal reference template
function template<typename T>
void process(T&& arg) {
std::cout << "Value: " << arg << std::endl;
}
int main() {
int x = 42;
process(x); // lvalue: copies
process(42); // rvalue: moves
process(std::move(x)); // rvalue: moves
return 0;
}Question 35
In a function that performs complex computation with intermediate results, what return type deduction provides the most maintainable implementation?
#include <iostream>
#include <vector>
// Auto return type deduction
auto computeResult(int x, double y) {
auto intermediate = x * 2.0;
auto result = intermediate + y;
return result; // Returns double
}
int main() {
auto value = computeResult(5, 3.14);
std::cout << value;
return 0;
}Question 36
When designing overloaded functions for arithmetic operations on user-defined types, what parameter passing convention provides the most intuitive and efficient implementation?
#include <iostream>
class Matrix {
// Matrix implementation
public:
Matrix operator+(const Matrix& other) const; // Member
};
Matrix operator*(const Matrix& a, const Matrix& b); // Global
int main() {
Matrix m1, m2, m3;
Matrix sum = m1 + m2; // Natural syntax
Matrix prod = m1 * m2; // Also natural
return 0;
}Question 37
In a function that must handle both success and failure cases with detailed error information, what return type provides the most expressive error handling?
#include <iostream>
#include <variant>
#include <string>
std::variant<int, std::string> divide(int a, int b) {
if (b == 0) {
return "Division by zero"; // Error case
}
return a / b; // Success case
}
int main() {
auto result = divide(10, 0);
if (std::holds_alternative<std::string>(result)) {
std::cout << std::get<std::string>(result);
} else {
std::cout << std::get<int>(result);
}
return 0;
}Question 38
When implementing a function that must work with any callable object (function, lambda, functor), what parameter type provides the most flexible interface?
#include <iostream>
#include <functional>
void executeCallback(std::function<void(int)> callback) {
callback(42);
}
void myFunction(int x) {
std::cout << "Called with: " << x << std::endl;
}
int main() {
executeCallback(myFunction); // Function pointer
executeCallback([](int x) { // Lambda
std::cout << "Lambda: " << x << std::endl;
});
return 0;
}Question 39
In a function template that must handle containers with different value types, what concept or constraint provides the most readable type requirements?
#include <iostream>
#include <vector>
#include <list>
// Template with concepts (C++20)
template<typename Container>
requires std::ranges::range<Container>
void printContainer(const Container& c) {
for (const auto& item : c) {
std::cout << item << " ";
}
std::cout << std::endl;
}
int main() {
std::vector<int> v = {1, 2, 3};
printContainer(v);
return 0;
}Question 40
When designing a function that must handle both compile-time and runtime constants efficiently, what combination of specifiers provides the most optimization opportunities?
#include <iostream>
// Constexpr function for compile-time evaluation
constexpr int factorial(int n) {
int result = 1;
for(int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
int main() {
constexpr int compileTime = factorial(5); // Compile-time
int runtime = factorial(5); // Runtime
std::cout << compileTime << " " << runtime;
return 0;
}