Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions solutions/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Ignore executables created by the solutions
4-pointers/pointers
5-templates/part2/main
6.1-my-array/part1
6.1-my-array/part2
6.1-my-array/part3
Expand Down
10 changes: 10 additions & 0 deletions solutions/5-templates/part2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CXXFLAGS = --std=c++20

main : main.o
$(CXX) $^ -o $@

run : main
./main

clean :
rm -rf *.o main
54 changes: 54 additions & 0 deletions solutions/5-templates/part2/array.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef CPPEX_ARRAY_HPP
#define CPPEX_ARRAY_HPP

#include <iostream>

// Add template parameters to set the data type and array size at compile time
template <typename T, unsigned int N>
class FixedSizeArray {

private:
T data[N];

public:

FixedSizeArray() {
for (int i = 0; i < N; ++i) {
data[i] = T(); // Initialise values by calling type's default constructor
}
}

// Overload the [] operator to provide access to the array elements
T& operator[](int index) {
return data[index];
}

const T& operator[](int index) const {
return data[index];
}

// Create function size() that returns the size of the array
unsigned int size() const { return N; }

// Create function reduce() that sums all elements of the array
T reduce() const {
T result = data[0];
for (int i = 1; i < N; ++i) {
result += data[i];
}
return result;
}

// Create function doubleInPlace() that doubles each element of the array
void doubleInPlace() {
if constexpr (std::is_arithmetic<T>()) {
for (int i = 0; i < N; ++i) {
data[i] *= 2;
}
} else {
std::cout << "ERROR: Cannot double array values. Data type is not arithmetic" << std::endl;
}
}
};

#endif
56 changes: 56 additions & 0 deletions solutions/5-templates/part2/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "array.hpp"

void print(auto&& arr) {
/* Helper function to print the contents of a FixedSizeArray */
std::cout << "[ " << arr[0];
for (int i = 1; i < arr.size(); ++i) {
std::cout << ", " << arr[i];
}
std::cout << " ]" << std::endl;
}

int main() {
// Initialise an empty fixed size array of 5 integers
FixedSizeArray<int, 5> arr;
std::cout << "Array size: " << arr.size() << std::endl;
print(arr);

// Use a for loop to set the array values. E.g. 1-5
for (int i = 0; i < arr.size(); ++i) {
arr[i] = i + 1;
}
print(arr);

// Call doubleInPlace() and print the new array
arr.doubleInPlace();
print(arr);

// Initialise an empty fixed size array of 5 integers with the const specifier
const FixedSizeArray<int, 5> constArr = arr;
print(constArr);

// Print the output of calling reduce()
std::cout << constArr.reduce() << std::endl;

// Check you get a compile time error if you try to set an element value in the
// const array, or if you call doubleInPlace()
// constArr[0] = 1;
// constArr.doubleInPlace();

// Initialise a fixed size array of strings with element values "Hello" and "World!"
FixedSizeArray<std::string, 2> strArr;
strArr[0] = "Hello";
strArr[1] = "World!";
std::cout << "strArr size: " << strArr.size() << std::endl;
print(strArr);

// Print the output of calling reduce() on strArr
std::cout << "strArr reduction: " << strArr.reduce() << std::endl;

// Call doubleInPlace(). What happens? Can you explain this?
// EXTENSION: Can you change the behaviour of doubleInPlace for non numeric data types?
// E.g. Just print an error and leave the array unchanged.
// Hint: You may want to search for useful type traits, and look up 'if constexpr'.
strArr.doubleInPlace();
print(strArr);
}