commit a67325eb6c28db74bb43e9197ba5eaa4afb3faf9
parent 8d22581197d69a18816496fb3693e16b8f04b350
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Fri, 14 Jul 2023 22:55:37 +0100
template-specialisation: Example showing type-erased unique pointer
Diffstat:
1 file changed, 87 insertions(+), 0 deletions(-)
diff --git a/src/template_specialisation.cpp b/src/template_specialisation.cpp
@@ -0,0 +1,87 @@
+#include <utility>
+#include <memory>
+#include <iostream>
+
+template <typename T = void>
+struct S
+{
+ S() = default;
+
+ explicit S(T* p)
+ : p(p)
+ {}
+
+ ~S()
+ {
+ if (p)
+ delete p;
+ }
+ S(S&& old)
+ : p{std::exchange(old.p, nullptr)}
+ {}
+
+ S& operator =(S&& old)
+ {
+ if (p)
+ delete p;
+ p = std::exchange(old.p, nullptr);
+ return *this;
+ }
+private:
+ T* p = nullptr;
+
+ friend struct S<void>;
+};
+
+template<>
+struct S<void>
+{
+ S() = default;
+
+ ~S()
+ {
+ if (p)
+ d(p);
+ }
+
+ S(S&& old)
+ : p{std::exchange(old.p, nullptr)}
+ , d{std::exchange(old.d, nullptr)}
+ {}
+
+ S& operator =(S&& old)
+ {
+ if (p)
+ d(p);
+ p = std::exchange(old.p, nullptr);
+ d = std::exchange(old.d, nullptr);
+ return *this;
+ }
+
+ template <typename T>
+ S(S<T>&& old)
+ : p{std::exchange(old.p, nullptr)}
+ , d{[](void* x) { delete (T*)x; }}
+ {}
+
+private:
+ void* p = nullptr;
+ void (*d)(void*) = nullptr;
+};
+
+struct sentry
+{
+ sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
+ ~sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
+};
+
+int main()
+{
+ S<> s2;
+ {
+ S<sentry> s1{new sentry};
+ s2 = std::move(s1);
+ std::cout << "~s1\n";
+ }
+ std::cout << "~s2\n";
+}