cpp
exercises
exercises.cpp⚙️cpp
/**
* Class Templates - Exercises
* Compile: g++ -std=c++17 -Wall exercises.cpp -o exercises
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// ============================================================
// Exercise 1: Simple Container ⭐
// ============================================================
// TODO: Create template class 'Container' with:
// - Private member 'value' of type T
// - Constructor taking T
// - get() and set() methods
void exercise1() {
// Container<int> c1(42);
// Container<string> c2("Hello");
// cout << c1.get() << endl;
// c1.set(100);
cout << "(Implement Container template)" << endl;
}
// ============================================================
// Exercise 2: Queue Template ⭐⭐
// ============================================================
// TODO: Create template class 'Queue' with:
// - enqueue(T) - add to back
// - dequeue() - remove from front
// - front() - peek front
// - empty(), size()
void exercise2() {
// Queue<int> q;
// q.enqueue(1); q.enqueue(2); q.enqueue(3);
// while (!q.empty()) cout << q.dequeue() << " ";
cout << "(Implement Queue template)" << endl;
}
// ============================================================
// Exercise 3: Fixed Array ⭐⭐
// ============================================================
// TODO: Create template 'FixedArray<T, N>' with:
// - operator[] for access
// - size() returning N
// - fill(value) to set all elements
// - at(i) with bounds checking
void exercise3() {
// FixedArray<int, 5> arr;
// arr.fill(0);
// arr[2] = 42;
// cout << arr.at(2) << endl;
cout << "(Implement FixedArray template)" << endl;
}
// ============================================================
// Exercise 4: Pair with Methods ⭐⭐
// ============================================================
// TODO: Create 'KeyValue<K, V>' template with:
// - key and value members
// - getKey(), getValue()
// - setKey(), setValue()
// - swap() to swap key and value (if same type)
void exercise4() {
// KeyValue<string, int> kv("age", 25);
// cout << kv.getKey() << ": " << kv.getValue() << endl;
cout << "(Implement KeyValue template)" << endl;
}
// ============================================================
// Exercise 5: Static Counter ⭐⭐⭐
// ============================================================
// TODO: Create 'Tracker<T>' that counts:
// - Total instances created (static)
// - Currently alive instances (static)
void exercise5() {
// { Tracker<int> a, b, c; }
// cout << Tracker<int>::totalCreated() << endl; // 3
// cout << Tracker<int>::currentlyAlive() << endl; // 0
cout << "(Implement Tracker with static counters)" << endl;
}
// ============================================================
// Exercise 6: Specialization ⭐⭐⭐
// ============================================================
// TODO: Create 'Serializer<T>' with serialize() method
// Specialize for: int, double, string, bool
// Each returns appropriate string representation
void exercise6() {
// Serializer<int> si;
// Serializer<bool> sb;
// cout << si.serialize(42) << endl; // "42"
// cout << sb.serialize(true) << endl; // "true"
cout << "(Implement Serializer with specializations)" << endl;
}
// ============================================================
// Exercise 7: Smart Pointer ⭐⭐⭐
// ============================================================
// TODO: Create simple 'SmartPtr<T>' that:
// - Takes ownership of a pointer
// - Deletes in destructor
// - Has operator* and operator->
// - Non-copyable, movable
void exercise7() {
// SmartPtr<int> p(new int(42));
// cout << *p << endl;
// SmartPtr<string> s(new string("Hello"));
// cout << s->length() << endl;
cout << "(Implement SmartPtr template)" << endl;
}
// ============================================================
// Exercise 8: Matrix Template ⭐⭐⭐
// ============================================================
// TODO: Create 'Matrix<T, Rows, Cols>' with:
// - operator()(row, col) for access
// - rows(), cols() methods
// - fill(value) method
void exercise8() {
// Matrix<int, 3, 3> m;
// m.fill(0);
// m(1, 1) = 5;
// cout << m(1, 1) << endl;
cout << "(Implement Matrix template)" << endl;
}
// ============================================================
// MAIN
// ============================================================
int main() {
cout << "=== Class Templates Exercises ===" << endl;
cout << "\nEx1: Container" << endl;
exercise1();
cout << "\nEx2: Queue" << endl;
exercise2();
cout << "\nEx3: FixedArray" << endl;
exercise3();
cout << "\nEx4: KeyValue" << endl;
exercise4();
cout << "\nEx5: Tracker" << endl;
exercise5();
cout << "\nEx6: Serializer" << endl;
exercise6();
cout << "\nEx7: SmartPtr" << endl;
exercise7();
cout << "\nEx8: Matrix" << endl;
exercise8();
return 0;
}
// ============================================================
// ANSWERS
// ============================================================
/*
Ex1:
template<typename T>
class Container {
T value;
public:
Container(T v) : value(v) {}
T get() const { return value; }
void set(T v) { value = v; }
};
Ex2:
template<typename T>
class Queue {
vector<T> data;
public:
void enqueue(T v) { data.push_back(v); }
T dequeue() { T f = data.front(); data.erase(data.begin()); return f; }
T front() const { return data.front(); }
bool empty() const { return data.empty(); }
size_t size() const { return data.size(); }
};
Ex3:
template<typename T, size_t N>
class FixedArray {
T data[N];
public:
T& operator[](size_t i) { return data[i]; }
constexpr size_t size() const { return N; }
void fill(T v) { for (auto& x : data) x = v; }
T& at(size_t i) { if (i >= N) throw out_of_range(""); return data[i]; }
};
Ex5:
template<typename T>
class Tracker {
static int created, alive;
public:
Tracker() { ++created; ++alive; }
~Tracker() { --alive; }
static int totalCreated() { return created; }
static int currentlyAlive() { return alive; }
};
template<typename T> int Tracker<T>::created = 0;
template<typename T> int Tracker<T>::alive = 0;
Ex7:
template<typename T>
class SmartPtr {
T* ptr;
public:
SmartPtr(T* p) : ptr(p) {}
~SmartPtr() { delete ptr; }
SmartPtr(const SmartPtr&) = delete;
SmartPtr& operator=(const SmartPtr&) = delete;
T& operator*() { return *ptr; }
T* operator->() { return ptr; }
};
*/