C++ Advanced Templates Quiz

C++
0 Passed
0% acceptance

40 in-depth questions covering advanced C++ template metaprogramming with SFINAE, variadic templates, constexpr, and compile-time computation — with 16 code examples to solidify understanding.

40 Questions
~80 minutes
1

Question 1

What is SFINAE (Substitution Failure is Not An Error)?

cpp
template <typename T>
auto func(T t) -> decltype(t.begin(), void()) {
    // Only enabled if T has begin() member
    std::cout << "Container\n";
}

template <typename T>
auto func(T t) -> decltype(t++, void()) {
    // Only enabled if T supports postfix ++
    std::cout << "Iterator\n";
}

// SFINAE: if substitution fails, overload is discarded, not error
A
Template metaprogramming principle where invalid template argument substitutions cause overload candidates to be discarded rather than compilation errors, enabling conditional compilation
B
Principle that causes compilation errors
C
Principle that prevents template substitution
D
Principle that requires all substitutions to succeed
2

Question 2

What is std::enable_if and how does it work?

cpp
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void func(T value) {
    std::cout << "Integral: " << value << std::endl;
}

// Only enabled for integral types
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
void func(T value) {
    std::cout << "Floating: " << value << std::endl;
}

func(42);    // Calls integral version
func(3.14);  // Calls floating version
A
Template metafunction that enables function/template instantiation only when condition is true, using SFINAE to conditionally compile based on type traits
B
Template that always enables compilation
C
Template that prevents compilation
D
Template that ignores conditions
3

Question 3

What are variadic templates?

cpp
template <typename... Args>
void print_all(Args... args) {
    // Parameter pack expansion
    (std::cout << ... << args) << std::endl;
}

// Recursive unpacking
template <typename T, typename... Rest>
void print_recursive(T first, Rest... rest) {
    std::cout << first << " ";
    print_recursive(rest...);
}

print_all(1, 2.5, "hello"); // 1 2.5 hello
A
Templates accepting variable number of template arguments through parameter packs, enabling functions and classes that work with arbitrary number of types
B
Templates with fixed arguments
C
Templates that prevent arguments
D
Templates with no arguments
4

Question 4

What are fold expressions in C++17?

cpp
template <typename... Args>
auto sum(Args... args) {
    return (args + ...); // Binary fold: ((arg1 + arg2) + arg3) + ...
}

template <typename... Args>
auto all_true(Args... args) {
    return (args && ...); // Left fold with &&
}

template <typename... Args>
auto any_true(Args... args) {
    return (... || args); // Right fold with ||
}

std::cout << sum(1, 2, 3, 4); // 10
A
C++17 feature providing concise syntax for reducing parameter packs with binary operators, supporting left/right folds and custom initial values
B
Feature that expands parameter packs
C
Feature that prevents folding
D
Feature that requires manual loops
5

Question 5

What is template specialization?

cpp
// Primary template
template <typename T>
struct Wrapper {
    void print() { std::cout << "Generic\n"; }
};

// Full specialization for int
template <>
struct Wrapper<int> {
    void print() { std::cout << "Int specialization\n"; }
};

// Partial specialization for pointers
template <typename T>
struct Wrapper<T*> {
    void print() { std::cout << "Pointer specialization\n"; }
};

Wrapper<double> w1; w1.print(); // Generic
Wrapper<int> w2; w2.print();     // Int specialization
Wrapper<int*> w3; w3.print();    // Pointer specialization
A
Providing alternative template implementations for specific types or type patterns, allowing customization of generic behavior for particular cases
B
Preventing template instantiation
C
Creating generic templates
D
Ignoring template arguments
6

Question 6

What is constexpr in template metaprogramming?

cpp
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

// Compile-time computation
template <int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};

template <>
struct Factorial<0> {
    static constexpr int value = 1;
};

std::array<int, Factorial<5>::value> arr; // Size computed at compile-time
A
Specifier allowing functions and variables to be evaluated at compile-time, enabling template metaprogramming and static initialization with computed values
B
Specifier that prevents compile-time evaluation
C
Specifier that requires runtime evaluation
D
Specifier that ignores computation
7

Question 7

What is tag dispatch?

cpp
struct integral_tag {};
struct floating_tag {};
struct other_tag {};

template <typename T>
struct tag {
    using type = other_tag;
};

template <>
struct tag<int> {
    using type = integral_tag;
};

void process_impl(int value, integral_tag) {
    std::cout << "Processing int: " << value << std::endl;
}

void process_impl(double value, floating_tag) {
    std::cout << "Processing double: " << value << std::endl;
}

template <typename T>
void process(T value) {
    process_impl(value, typename tag<T>::type{});
}
A
Technique using tag types to dispatch to different function implementations based on type traits, providing cleaner alternative to SFINAE for conditional compilation
B
Technique that prevents function dispatch
C
Technique that requires single implementation
D
Technique that ignores types
8

Question 8

What are template template parameters?

cpp
template <template <typename, typename> class Container, typename T, typename Alloc>
class Wrapper {
    Container<T, Alloc> data;
public:
    void add(const T& value) { data.push_back(value); }
};

// Usage
Wrapper<std::vector, int, std::allocator<int>> vec_wrapper;
Wrapper<std::deque, std::string, std::allocator<std::string>> deque_wrapper;

// Container type is parameterized
template <typename T>
using MyVector = Wrapper<std::vector, T, std::allocator<T>>;
A
Template parameters that accept template types as arguments, enabling higher-order generic programming where container types themselves are parameterized
B
Parameters that prevent templates
C
Parameters that require concrete types
D
Parameters that ignore templates
9

Question 9

What is CRTP (Curiously Recurring Template Pattern)?

cpp
template <typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }
    
    void common_function() {
        std::cout << "Common behavior\n";
    }
};

class Concrete : public Base<Concrete> {
public:
    void implementation() {
        std::cout << "Concrete implementation\n";
    }
};

Concrete c;
c.interface(); // Calls Concrete::implementation()
c.common_function(); // Calls Base::common_function()
A
Pattern where derived class passes itself as template parameter to base class, enabling static polymorphism and compile-time method resolution
B
Pattern that prevents inheritance
C
Pattern that requires runtime polymorphism
D
Pattern that ignores derived classes
10

Question 10

What is decltype and how is it used in templates?

cpp
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}

// Trailing return type with decltype
std::vector<int> vec = {1, 2, 3};
auto it = vec.begin();
decltype(*it) value = *it; // int

decltype(auto) func() {
    return 42; // Return type is int
}
A
Operator determining type of expression at compile-time, enabling template functions to deduce return types and create generic type-safe operations
B
Operator that ignores expression types
C
Operator that requires explicit types
D
Operator that prevents type deduction
11

Question 11

What is template argument deduction?

cpp
// Function template deduction
template <typename T>
void func(T param) {
    std::cout << typeid(T).name() << std::endl;
}

func(42);     // T = int
func(3.14);   // T = double
func("hello"); // T = const char*

// Class template deduction (C++17)
std::pair p(1, 2.5); // std::pair<int, double>
std::vector v{1, 2, 3}; // std::vector<int>
A
Compiler mechanism automatically determining template arguments from function call arguments, eliminating need for explicit template parameter specification
B
Mechanism that requires explicit parameters
C
Mechanism that prevents template usage
D
Mechanism that ignores arguments
12

Question 12

What is partial template specialization?

cpp
// Primary template
template <typename T, typename U>
struct Pair {
    T first;
    U second;
};

// Partial specialization for same types
template <typename T>
struct Pair<T, T> {
    T both;
    Pair(T val) : both(val) {}
};

// Partial specialization for pointers
template <typename T, typename U>
struct Pair<T*, U*> {
    T* first;
    U* second;
    
    Pair(T* f, U* s) : first(f), second(s) {}
};

Pair<int, double> p1;      // Primary
Pair<int, int> p2(42);     // Same types specialization
Pair<int*, double*> p3;    // Pointer specialization
A
Specializing template for subset of possible template arguments while leaving others generic, enabling customized behavior for type patterns
B
Specializing all template arguments
C
Preventing template specialization
D
Ignoring template arguments
13

Question 13

What is if constexpr in C++17?

cpp
template <typename T>
auto process(T value) {
    if constexpr (std::is_integral_v<T>) {
        return value * 2; // Compile-time branch
    } else if constexpr (std::is_floating_point_v<T>) {
        return value * 2.0;
    } else {
        static_assert(false, "Unsupported type");
    }
}

// Only true branch is compiled
int result = process(42);     // Only int branch compiled
double result2 = process(3.14); // Only double branch compiled
A
C++17 feature enabling compile-time conditional execution where only true branches are instantiated, eliminating runtime overhead of template conditionals
B
Feature that executes all branches
C
Feature that prevents conditional execution
D
Feature that requires runtime evaluation
14

Question 14

What are type traits?

cpp
#include <type_traits>

// Primary template
struct is_pointer : std::false_type {};

// Specialization for pointers
template <typename T>
struct is_pointer<T*> : std::true_type {};

// Usage
static_assert(is_pointer<int*>::value, "int* should be pointer");
static_assert(!is_pointer<int>::value, "int should not be pointer");

// Standard type traits
std::cout << std::is_integral<int>::value;     // true
std::cout << std::is_floating_point<double>::value; // true
A
Template metafunctions providing compile-time type information and classification, enabling conditional compilation based on type properties
B
Traits that provide runtime type information
C
Traits that ignore type properties
D
Traits that prevent compilation
15

Question 15

What is parameter pack expansion?

cpp
template <typename... Args>
void print_all(Args... args) {
    // Expand with comma separator
    std::cout << ((std::to_string(args) + " ") + ...);
}

// Expand into function calls
template <typename... Args>
void call_functions(Args... funcs) {
    (funcs(), ...); // Call each function
}

// Expand into template instantiations
template <typename... Types>
struct Tuple {
    std::tuple<Types...> data;
};

print_all(1, 2, 3); // "1 2 3 "
A
Mechanism unpacking variadic template parameter packs into separate arguments using ... operator, enabling iteration over template arguments
B
Mechanism that packs parameters
C
Mechanism that prevents expansion
D
Mechanism that requires fixed parameters
16

Question 16

What is template recursion and compile-time computation?

cpp
// Factorial at compile-time
template <int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};

template <>
struct Factorial<0> {
    static constexpr int value = 1;
};

// Fibonacci
template <int N>
struct Fibonacci {
    static constexpr int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};

template <>
struct Fibonacci<0> {
    static constexpr int value = 0;
};

template <>
struct Fibonacci<1> {
    static constexpr int value = 1;
};

std::array<int, Factorial<5>::value> arr; // Size = 120
A
Using recursive template instantiation to perform computation during compilation, enabling complex algorithms to execute at compile-time with zero runtime cost
B
Performing computation at runtime
C
Preventing recursive instantiation
D
Requiring runtime recursion
17

Question 17

What is perfect forwarding in templates?

cpp
template <typename T>
void wrapper(T&& arg) {
    // Forward preserves value category
    func(std::forward<T>(arg));
}

void func(int& x) { std::cout << "Lvalue\n"; }
void func(int&& x) { std::cout << "Rvalue\n"; }

int x = 42;
wrapper(x);      // Calls func(int&) - lvalue preserved
wrapper(42);     // Calls func(int&&) - rvalue preserved
wrapper(std::move(x)); // Calls func(int&&) - rvalue preserved
A
Technique using universal references and std::forward to preserve argument value categories when passing them to other functions
B
Technique that changes value categories
C
Technique that prevents forwarding
D
Technique that requires copying
18

Question 18

What is static_assert in template metaprogramming?

cpp
template <typename T>
class Container {
    static_assert(std::is_copy_constructible_v<T>, 
                  "T must be copy constructible");
    
    static_assert(sizeof(T) <= 1000, 
                  "T is too large for this container");
    
    T data;
};

// Compilation fails with clear error messages
Container<NonCopyable> bad1; // Error: T must be copy constructible
Container<HugeStruct> bad2;  // Error: T is too large...
A
Compile-time assertion providing clear error messages when template constraints are violated, enabling better template debugging and API design
B
Assertion that occurs at runtime
C
Assertion that prevents compilation
D
Assertion that ignores constraints
19

Question 19

What is template non-type parameters?

cpp
// Integer parameters
template <int Size>
class Array {
    int data[Size];
};

// Pointer parameters
template <char* const Str>
struct StringLiteral {
    static constexpr const char* value = Str;
};

// Usage
Array<10> arr; // Size = 10
StringLiteral<"hello"> str; // Str = "hello"

// Template variables (C++14)
template <auto Value>
constexpr auto constant = Value;

auto x = constant<42>; // x = 42
A
Template parameters that accept constant values rather than types, enabling compile-time constants to parameterize template behavior
B
Parameters that accept runtime values
C
Parameters that prevent constants
D
Parameters that require types only
20

Question 20

What is the difference between typename and class in template parameters?

cpp
// Completely interchangeable
template <typename T> class A {}; // Same as:
template <class T> class B {};    // Same

// But typename required in dependent contexts
template <typename T>
void func() {
    typename T::iterator it; // typename required
    T::value_type val;       // No typename needed in C++20
}

// typename in template template parameters
template <template <typename> typename Container>
class Wrapper {
    Container<int> data;
};
A
typename and class are synonymous for template type parameters, but typename is required to specify dependent types in template definitions
B
They have completely different meanings
C
typename is only for classes
D
class is only for templates
21

Question 21

What is template argument deduction for constructors?

cpp
template <typename T>
struct Wrapper {
    T value;
    
    // Deduction guide
    template <typename U>
    Wrapper(U&& val) -> Wrapper<std::decay_t<U>>;
};

// Usage - T deduced from constructor argument
Wrapper w1(42);     // Wrapper<int>
Wrapper w2(3.14);   // Wrapper<double>
Wrapper w3("hello"); // Wrapper<const char*>

// Without deduction guide, would need:
Wrapper<int> w4(42); // Explicit type required
A
C++17 feature allowing template arguments to be deduced from constructor arguments using deduction guides, enabling concise object construction
B
Feature that requires explicit template arguments
C
Feature that prevents constructor usage
D
Feature that ignores constructor arguments
22

Question 22

What is dependent name lookup in templates?

cpp
template <typename T>
void func(T t) {
    t.begin(); // Dependent name - depends on T
    
    // May need typename for dependent types
    typename T::iterator it = t.begin();
    
    // Two-phase lookup: names looked up twice
    // 1. Template definition time (non-dependent names)
    // 2. Template instantiation time (dependent names)
}

struct Container {
    void begin() { std::cout << "begin\n"; }
    using iterator = int*;
};

func(Container{}); // Dependent names resolved at instantiation
A
Two-phase name lookup process where dependent names are resolved at template instantiation time, requiring typename for dependent types
B
Lookup that occurs only at definition time
C
Lookup that prevents name resolution
D
Lookup that ignores dependencies
23

Question 23

What is template instantiation and when does it occur?

cpp
// Template definition
template <typename T>
T add(T a, T b) { return a + b; }

// Point of instantiation
int main() {
    int result = add(1, 2); // Template instantiated here with T=int
    
    // Implicit instantiation
    double result2 = add(1.0, 2.0); // T=double
    
    // Explicit instantiation (rare)
    template int add<int>(int, int);
}

// Each unique set of template arguments creates separate instantiation
A
Process where compiler generates concrete code from template by substituting actual types, occurring when template is first used with specific arguments
B
Process that occurs at template definition
C
Process that prevents code generation
D
Process that requires manual instantiation
24

Question 24

What is ADL (Argument Dependent Lookup)?

cpp
namespace MyNamespace {
    class MyClass {};
    
    void func(MyClass) {
        std::cout << "MyNamespace::func\n";
    }
}

// ADL finds func in MyNamespace
MyNamespace::MyClass obj;
func(obj); // Calls MyNamespace::func via ADL

// Without ADL, would need:
MyNamespace::func(obj); // Explicit qualification
A
Compiler mechanism searching for function names in namespaces of function arguments, enabling operator overloading and template-friendly function calls
B
Lookup that searches globally only
C
Lookup that prevents function finding
D
Lookup that requires explicit qualification
25

Question 25

What is template default arguments?

cpp
// Function template defaults
template <typename T = int>
void func(T value = 0) {
    std::cout << value << std::endl;
}

func();        // T=int, value=0
func(3.14);    // T=double, value=3.14

// Class template defaults
template <typename T = int, typename Alloc = std::allocator<T>>
class Vector {
    // ...
};

Vector<> v1;        // Vector<int, allocator<int>>
Vector<double> v2;  // Vector<double, allocator<double>>
A
Template parameters with default values that are used when arguments not explicitly provided, enabling optional template customization
B
Arguments that cannot be defaulted
C
Arguments that require explicit values
D
Arguments that prevent defaults
26

Question 26

What is the difference between function templates and class templates?

cpp
// Function template - argument deduction
template <typename T>
T max(T a, T b) { return a > b ? a : b; }

int result = max(1, 2); // T deduced as int

// Class template - explicit or deduced
template <typename T>
class Stack {
    T data;
};

Stack<int> s1;        // Explicit
Stack s2(42);         // Deduced (C++17)

// Function templates can be specialized
// Class templates can have partial specialization
A
Function templates support argument deduction and overloading, class templates require explicit instantiation but support partial specialization
B
They are identical
C
Function templates require explicit arguments
D
Class templates support deduction
27

Question 27

What is template metaprogramming recursion depth limits?

cpp
// Deep recursion may hit compiler limits
template <int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};

template <>
struct Factorial<0> {
    static constexpr int value = 1;
};

// Very deep recursion may fail
// Factorial<1000>::value; // May exceed compiler limits

// Solution: Use constexpr functions for deep recursion
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

constexpr int result = factorial(1000); // OK
A
Compiler limitations on recursive template instantiation depth, typically around 1000+ levels, requiring constexpr functions for very deep recursion
B
Limits that prevent any recursion
C
Limits that allow unlimited recursion
D
Limits that only apply to runtime
28

Question 28

What is the difference between constexpr and const?

cpp
const int runtime_const = 42; // Runtime constant
constexpr int compile_const = 42; // Compile-time constant

// constexpr can be used in template parameters
template <constexpr int N>
class Array {
    int data[N]; // N must be compile-time constant
};

// constexpr functions
constexpr int square(int x) { return x * x; }

int arr[square(3)]; // OK - computed at compile-time
Array<square(4)> arr2; // OK - used as template parameter
A
constexpr guarantees compile-time evaluation and enables use in contexts requiring constant expressions, const only prevents modification
B
They are identical
C
const guarantees compile-time evaluation
D
constexpr only prevents modification
29

Question 29

What is template alias (using) in C++11?

cpp
// Type alias
template <typename T>
using Vec = std::vector<T, std::allocator<T>>;

Vec<int> v1; // std::vector<int, allocator<int>>

// Template alias
template <typename T>
using FuncPtr = void(*)(T);

FuncPtr<int> fp; // void(*)(int)

// Complex aliases
template <typename Key, typename Value>
using MapAllocator = std::allocator<std::pair<const Key, Value>>;

template <typename Key, typename Value>
using MyMap = std::map<Key, Value, std::less<Key>, MapAllocator<Key, Value>>;
A
C++11 feature creating template-based type aliases using 'using' syntax, providing cleaner names for complex template instantiations
B
Feature that creates runtime aliases
C
Feature that prevents aliasing
D
Feature that requires typedef
30

Question 30

What is the difference between template specialization and overloading?

cpp
// Overloading - different functions
template <typename T>
void func(T) { std::cout << "Generic\n"; }

void func(int) { std::cout << "Int overload\n"; }

// Specialization - same template, different implementation
template <typename T>
struct Wrapper { void print() { std::cout << "Generic\n"; } };

template <>
struct Wrapper<int> { void print() { std::cout << "Int specialization\n"; } };

func(42);     // Calls overload
func(3.14);   // Calls template

Wrapper<double> w1; w1.print(); // Generic
Wrapper<int> w2; w2.print();     // Specialization
A
Overloading creates separate functions with different signatures, specialization provides alternative implementation for same template with specific arguments
B
They are identical
C
Overloading requires same signature
D
Specialization creates different functions
31

Question 31

What is the template keyword in dependent contexts?

cpp
template <typename T>
struct Container {
    using value_type = T;
    
    template <typename U>
    void func(U val) {}
};

template <typename T>
void process(Container<T> c) {
    // Dependent name - need 'template'
    c.template func<int>(42);
    
    // Dependent type - need 'typename'
    typename Container<T>::value_type val;
    
    // Non-dependent names don't need keywords
    std::cout << "Processing\n";
}
A
Keyword disambiguating dependent template names from comparisons, required when calling member templates in dependent contexts
B
Keyword that prevents template usage
C
Keyword that is always required
D
Keyword that is never needed
32

Question 32

What is universal reference (forwarding reference)?

cpp
template <typename T>
void func(T&& arg) { // Universal reference
    // T&& is rvalue reference if T is concrete type
    // T&& is forwarding reference if T is template parameter
}

// Perfect forwarding
template <typename T>
void wrapper(T&& arg) {
    func(std::forward<T>(arg)); // Preserves value category
}

int x = 42;
wrapper(x);      // arg is lvalue reference
wrapper(42);     // arg is rvalue reference
wrapper(std::move(x)); // arg is rvalue reference
A
T&& syntax that can bind to both lvalues and rvalues, enabling perfect forwarding when combined with std::forward
B
Reference that can only bind to rvalues
C
Reference that can only bind to lvalues
D
Reference that cannot bind to anything
33

Question 33

What is the difference between auto and decltype(auto)?

cpp
auto x = 42;        // int

const auto& ref = x; // const int&

auto func() {
    return 42;     // Return type is int
}

decltype(auto) func2() {
    return 42;     // Return type is int (same as auto here)
}

int y = 42;
int& ref_y = y;

auto x2 = ref_y;      // int (reference stripped)
decltype(auto) x3 = ref_y; // int& (reference preserved)

decltype(auto) func3() {
    static int x = 42;
    return (x);    // Return type is int& (reference to x)
}
A
auto strips references and cv-qualifiers from deduced types, decltype(auto) preserves them exactly as declared
B
They are identical
C
decltype(auto) strips references
D
auto preserves references
34

Question 34

What is template argument substitution and failure?

cpp
// Substitution failure example
template <typename T>
auto begin(T& t) -> decltype(t.begin()) {
    return t.begin();
}

// For types without begin(), substitution fails
// SFINAE: overload is discarded, not error

struct HasBegin {
    int* begin() { return nullptr; }
};

struct NoBegin {
    // No begin() member
};

HasBegin obj1;
begin(obj1); // OK - substitution succeeds

NoBegin obj2;
// begin(obj2); // Substitution fails, overload discarded
// If no other overloads, compilation error
A
Process where compiler substitutes template arguments into template, with SFINAE causing invalid substitutions to discard overloads rather than error
B
Process that always succeeds
C
Process that prevents substitution
D
Process that requires manual substitution
35

Question 35

What is the difference between member function templates and regular member functions?

cpp
class Container {
public:
    // Regular member function
    void assign(size_t count, int value) {
        // Specific implementation
    }
    
    // Member function template
    template <typename InputIt>
    void assign(InputIt first, InputIt last) {
        // Generic implementation
    }
};

Container c;
c.assign(5, 42);        // Calls regular member
c.assign(vec.begin(), vec.end()); // Calls template member

// Template members can be specialized
// Regular members cannot be templated on class level
A
Member function templates are parameterized on member function level, regular members have fixed signatures, enabling generic member implementations
B
They are identical
C
Regular members can be templated
D
Member templates have fixed signatures
36

Question 36

What is the difference between explicit and implicit template instantiation?

cpp
// Implicit instantiation
template <typename T>
T add(T a, T b) { return a + b; }

int result = add(1, 2); // Implicitly instantiates add<int>

// Explicit instantiation
template int add<int>(int, int); // Forces instantiation

// Explicit instantiation definition
template <typename T>
class MyClass {
    void func();
};

// In .cpp file:
template class MyClass<int>;        // Instantiate entire class
template void MyClass<int>::func(); // Instantiate specific member
A
Implicit instantiation occurs automatically when template used, explicit instantiation forces compilation of specific instantiations for separate compilation
B
They are identical
C
Explicit instantiation occurs automatically
D
Implicit instantiation forces compilation
37

Question 37

What is the difference between std::decay and std::remove_reference?

cpp
using T1 = std::remove_reference_t<int&>;     // int
using T2 = std::remove_reference_t<int&&>;    // int
using T3 = std::remove_reference_t<int>;      // int

using T4 = std::decay_t<int&>;                // int
using T5 = std::decay_t<int&&>;               // int
using T6 = std::decay_t<int>;                 // int
using T7 = std::decay_t<int[5]>;              // int*
using T8 = std::decay_t<const int>;           // int
using T9 = std::decay_t<void(int)>;           // void(*)(int)
A
remove_reference only strips references, decay performs full type decay including array-to-pointer and function-to-pointer conversions
B
They are identical
C
decay only strips references
D
remove_reference performs full decay
38

Question 38

What is the difference between template metaprogramming and constexpr programming?

cpp
// Template metaprogramming
template <int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};

template <>
struct Factorial<0> {
    static constexpr int value = 1;
};

// Constexpr programming
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

// Usage
std::array<int, Factorial<5>::value> arr1; // Template
constexpr int val = factorial(5);         // Constexpr
std::array<int, factorial(5)> arr2;       // Constexpr
A
Template metaprogramming uses recursive templates for compile-time computation, constexpr uses functions evaluated at compile-time with runtime-like syntax
B
They are identical
C
Template metaprogramming uses functions
D
Constexpr uses recursive templates
39

Question 39

What is the difference between std::enable_if and concepts (C++20)?

cpp
// enable_if approach
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
void func(T val) {}

// Concepts approach (C++20)
template <std::integral T>
void func(T val) {}

// More expressive concepts
template <typename T>
concept Addable = requires(T a, T b) { a + b; };

template <Addable T>
T add(T a, T b) { return a + b; }
A
enable_if uses SFINAE for conditional compilation with complex syntax, concepts provide cleaner syntax and better error messages for template constraints
B
They are identical
C
Concepts use SFINAE
D
enable_if provides cleaner syntax
40

Question 40

What are the fundamental principles for effective template metaprogramming in C++?

A
Use SFINAE and enable_if for conditional compilation, leverage constexpr for compile-time computation, understand template specialization and argument deduction, and use modern features like concepts when available
B
Never use templates
C
Use templates for everything
D
Ignore template constraints

QUIZZES IN C++