diff options
2 files changed, 93 insertions, 0 deletions
| -rw-r--r-- | Week11/Exercise02/Option.hpp | 68 | ||||
| -rw-r--r-- | Week11/Exercise02/main.cpp | 25 |
diff --git a/Week11/Exercise02/Option.hpp b/Week11/Exercise02/Option.hpp new file mode 100644 index 0000000..69f7297 --- /dev/null +++ b/Week11/Exercise02/Option.hpp @@ -0,0 +1,68 @@ +#ifndef _OPTION +#define _OPTION + +template <class T> +class Option { + T obj; + bool isSomething; + + Option(); +public: + static Option Some(T value); + static Option None(); + + bool IsSome() const; + bool IsNone() const; + T Unwrap(); +}; + +template <class T> +Option<T>::Option() : obj(), isSomething(false) +{ } + +template <class T> +Option<T> Option<T>::Some(T value) { + Option op; + op.isSomething = true; + op.obj = value; + return op; +} + +// Какво запазваме, когато искаме да запазим нищо? +// Ако работехме с T*, щяхме да запазим nullptr. +// В нашия случай, няма голямо значение каква е стойността на obj, +// затова просто ще запазим стойността по подразбиране. +// Ако съответния тип няма конструктор по подразбиране, тогава ще +// получим грешка по време на компилация. +template <class T> +Option<T> Option<T>::None() { + return Option(); +} + +template <class T> +bool Option<T>::IsSome() const { + return isSomething; +} + +template <class T> +bool Option<T>::IsNone() const { + return !isSomething; +} + +// Както при None метода, тук е нужно T да има имплементиран +// копиращи и/или преместващи семантики (конструктор и operator=). +// +// Обаче, ако ние сме създали обект чрез None, тогава Unwrap ще ни +// върне потенциално валидна стойност: тази по подразбиране. +// Коректното решение тук е да имаме проверка за isSomething, +// и ако не е, да "хвърлим грешка". Но това още не сме го учили. +// +// За момента ще приемем, че ако програмист направи Unwrap на обект, +// създаден чрез None, тогава това е негов пропуск, който сам трябва +// да си оправи. +template <class T> +T Option<T>::Unwrap() { + return obj; +} + +#endif /* _OPTION */ diff --git a/Week11/Exercise02/main.cpp b/Week11/Exercise02/main.cpp new file mode 100644 index 0000000..f734373 --- /dev/null +++ b/Week11/Exercise02/main.cpp @@ -0,0 +1,25 @@ +#include "Option.hpp" +#include <cmath> +#include <iostream> + +Option<double> trySqrt(double x) { + if (x < 0.0) + return Option<double>::None(); + return Option<double>::Some(sqrt(x)); +} + +int main() { + double num; + std::cin >> num; + + Option<double> numRoot = trySqrt(num); + + if (numRoot.IsSome()) { + std::cout << numRoot.Unwrap() << std::endl; + } + else { + std::cout << "Couldn't find square root!" << std::endl; + } + + return 0; +} |
