template_specialisation.cpp (1147B)
1 #include <utility> 2 #include <memory> 3 #include <iostream> 4 5 template <typename T = void> 6 struct S 7 { 8 S() = default; 9 10 explicit S(T* p) 11 : p(p) 12 {} 13 14 ~S() 15 { 16 if (p) 17 delete p; 18 } 19 S(S&& old) 20 : p{std::exchange(old.p, nullptr)} 21 {} 22 23 S& operator =(S&& old) 24 { 25 if (p) 26 delete p; 27 p = std::exchange(old.p, nullptr); 28 return *this; 29 } 30 private: 31 T* p = nullptr; 32 33 friend struct S<void>; 34 }; 35 36 template<> 37 struct S<void> 38 { 39 S() = default; 40 41 ~S() 42 { 43 if (p) 44 d(p); 45 } 46 47 S(S&& old) 48 : p{std::exchange(old.p, nullptr)} 49 , d{std::exchange(old.d, nullptr)} 50 {} 51 52 S& operator =(S&& old) 53 { 54 if (p) 55 d(p); 56 p = std::exchange(old.p, nullptr); 57 d = std::exchange(old.d, nullptr); 58 return *this; 59 } 60 61 template <typename T> 62 S(S<T>&& old) 63 : p{std::exchange(old.p, nullptr)} 64 , d{[](void* x) { delete (T*)x; }} 65 {} 66 67 private: 68 void* p = nullptr; 69 void (*d)(void*) = nullptr; 70 }; 71 72 struct sentry 73 { 74 sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; } 75 ~sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; } 76 }; 77 78 int main() 79 { 80 S<> s2; 81 { 82 S<sentry> s1{new sentry}; 83 s2 = std::move(s1); 84 std::cout << "~s1\n"; 85 } 86 std::cout << "~s2\n"; 87 }