cpp
examples
examples.cpp⚙️cpp
/**
* Advanced Templates - Examples
* Compile: g++ -std=c++17 -Wall examples.cpp -o examples
*/
#include <iostream>
#include <string>
#include <vector>
#include <type_traits>
using namespace std;
// ============================================================
// SECTION 1: VARIADIC TEMPLATES
// ============================================================
// Base case
void print() { cout << endl; }
// Recursive case
template<typename T, typename... Args>
void print(T first, Args... rest) {
cout << first;
if constexpr (sizeof...(rest) > 0) cout << ", ";
print(rest...);
}
template<typename... Args>
size_t countArgs(Args... args) {
return sizeof...(args);
}
void demoVariadic() {
cout << "--- Variadic Templates ---\n" << endl;
cout << " Print: ";
print(1, 2.5, "hello", 'x');
cout << " Count: " << countArgs(1, 2, 3, 4, 5) << " arguments" << endl;
}
// ============================================================
// SECTION 2: FOLD EXPRESSIONS (C++17)
// ============================================================
template<typename... Args>
auto sum(Args... args) {
return (... + args);
}
template<typename... Args>
auto product(Args... args) {
return (... * args);
}
template<typename... Args>
bool allTrue(Args... args) {
return (... && args);
}
template<typename... Args>
bool anyTrue(Args... args) {
return (... || args);
}
template<typename... Args>
void printAll(Args... args) {
cout << " ";
((cout << args << " "), ...);
cout << endl;
}
void demoFold() {
cout << "\n--- Fold Expressions ---\n" << endl;
cout << " sum(1,2,3,4,5) = " << sum(1,2,3,4,5) << endl;
cout << " product(1,2,3,4) = " << product(1,2,3,4) << endl;
cout << " allTrue(true,true,false) = " << boolalpha
<< allTrue(true,true,false) << endl;
cout << " anyTrue(false,false,true) = "
<< anyTrue(false,false,true) << endl;
cout << " printAll: ";
printAll(10, 20, 30);
}
// ============================================================
// SECTION 3: TYPE TRAITS
// ============================================================
template<typename T>
void analyzeType() {
cout << " is_integral: " << boolalpha << is_integral_v<T> << endl;
cout << " is_floating: " << is_floating_point_v<T> << endl;
cout << " is_pointer: " << is_pointer_v<T> << endl;
cout << " is_const: " << is_const_v<T> << endl;
}
void demoTypeTraits() {
cout << "\n--- Type Traits ---\n" << endl;
cout << " Analyzing int:" << endl;
analyzeType<int>();
cout << "\n Analyzing const double*:" << endl;
analyzeType<const double*>();
// Type modifications
cout << "\n Type modifications:" << endl;
cout << " same type (int, int): "
<< is_same_v<int, int> << endl;
cout << " same type (int, long): "
<< is_same_v<int, long> << endl;
}
// ============================================================
// SECTION 4: SFINAE
// ============================================================
// Enable only for integral types
template<typename T,
typename enable_if<is_integral_v<T>, int>::type = 0>
string getTypeName(T) {
return "integral";
}
// Enable only for floating point
template<typename T,
typename enable_if<is_floating_point_v<T>, int>::type = 0>
string getTypeName(T) {
return "floating point";
}
// Enable for pointers
template<typename T,
typename enable_if<is_pointer_v<T>, int>::type = 0>
string getTypeName(T) {
return "pointer";
}
void demoSFINAE() {
cout << "\n--- SFINAE ---\n" << endl;
cout << " 42 is: " << getTypeName(42) << endl;
cout << " 3.14 is: " << getTypeName(3.14) << endl;
int x = 10;
cout << " &x is: " << getTypeName(&x) << endl;
}
// ============================================================
// SECTION 5: IF CONSTEXPR
// ============================================================
template<typename T>
auto process(T value) {
if constexpr (is_integral_v<T>) {
return value * 2;
} else if constexpr (is_floating_point_v<T>) {
return value / 2.0;
} else {
return value;
}
}
template<typename T>
void describeType() {
if constexpr (is_same_v<T, int>) {
cout << " Type is int" << endl;
} else if constexpr (is_same_v<T, double>) {
cout << " Type is double" << endl;
} else if constexpr (is_same_v<T, string>) {
cout << " Type is string" << endl;
} else {
cout << " Type is unknown" << endl;
}
}
void demoIfConstexpr() {
cout << "\n--- if constexpr ---\n" << endl;
cout << " process(10) = " << process(10) << endl;
cout << " process(10.0) = " << process(10.0) << endl;
describeType<int>();
describeType<double>();
describeType<string>();
describeType<char>();
}
// ============================================================
// SECTION 6: COMPILE-TIME COMPUTATION
// ============================================================
template<unsigned N>
struct Factorial {
static constexpr unsigned value = N * Factorial<N-1>::value;
};
template<>
struct Factorial<0> {
static constexpr unsigned value = 1;
};
template<unsigned N>
struct Fibonacci {
static constexpr unsigned value =
Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};
template<> struct Fibonacci<0> { static constexpr unsigned value = 0; };
template<> struct Fibonacci<1> { static constexpr unsigned value = 1; };
void demoCompileTime() {
cout << "\n--- Compile-Time Computation ---\n" << endl;
cout << " Factorial<5> = " << Factorial<5>::value << endl;
cout << " Factorial<10> = " << Factorial<10>::value << endl;
cout << " Fibonacci<10> = " << Fibonacci<10>::value << endl;
cout << " Fibonacci<15> = " << Fibonacci<15>::value << endl;
}
// ============================================================
// SECTION 7: ADVANCED VARIADIC
// ============================================================
// Tuple-like structure
template<typename... Ts>
struct TypeList {};
template<typename T, typename... Ts>
struct TypeList<T, Ts...> {
using Head = T;
using Tail = TypeList<Ts...>;
static constexpr size_t size = 1 + sizeof...(Ts);
};
template<>
struct TypeList<> {
static constexpr size_t size = 0;
};
// Perfect forwarding factory
template<typename T, typename... Args>
T* create(Args&&... args) {
return new T(forward<Args>(args)...);
}
void demoAdvancedVariadic() {
cout << "\n--- Advanced Variadic ---\n" << endl;
using MyTypes = TypeList<int, double, string>;
cout << " TypeList size: " << MyTypes::size << endl;
cout << " Head is int: " << is_same_v<MyTypes::Head, int> << endl;
// Factory
string* str = create<string>("Hello, World!");
cout << " Created string: " << *str << endl;
delete str;
}
// ============================================================
// MAIN
// ============================================================
int main() {
cout << "╔══════════════════════════════════════╗" << endl;
cout << "║ ADVANCED TEMPLATES - EXAMPLES ║" << endl;
cout << "╚══════════════════════════════════════╝" << endl;
demoVariadic();
demoFold();
demoTypeTraits();
demoSFINAE();
demoIfConstexpr();
demoCompileTime();
demoAdvancedVariadic();
cout << "\n=== Complete ===" << endl;
return 0;
}