Ticket #11520: choose_deleter.cpp

File choose_deleter.cpp, 1.5 KB (added by fabian.kislat@…, 7 years ago)

Example, how one might handle all three cases: delete operator with one or two arguments, or no class specific delete at all using SFINAE

Line 
1#include <iostream>
2
3#include <boost/core/enable_if.hpp>
4
5
6template <typename T>
7struct HasDeleteOperator
8{
9 template <typename U, void (*)(void*, std::size_t)> struct SFINAE2 {};
10 template <typename U, void (*)(void*)> struct SFINAE1 {};
11 template <typename U> static char Test(SFINAE1<U, &U::operator delete>*);
12 template <typename U> static char Test(SFINAE2<U, &U::operator delete>*);
13 template <typename U> static int Test(...);
14 static const bool value = sizeof(Test<T>(0)) == sizeof(char);
15};
16
17
18template <typename T, class Enable = void>
19struct deleter {
20 static void invoke(T *t) {
21 std::cout << "Calling default operator delete" << std::endl;
22 (operator delete)(t);
23 }
24};
25
26
27template <typename T>
28struct deleter<T, typename boost::enable_if< HasDeleteOperator<T> >::type> {
29 template<void D(void *, std::size_t)>
30 static void use_delete_operator(void * t, std::size_t s){
31 std::cout << "Calling class-specific operator delete with two arguments" << std::endl;
32 D(t, s);
33 }
34
35 template<void D(void *)>
36 static void use_delete_operator(void * t, std::size_t s){
37 std::cout << "Calling class-specific operator delete with one argument" << std::endl;
38 D(t);
39 }
40
41 static void invoke(T *t) {
42 use_delete_operator<T::operator delete>(t, sizeof(T));
43 }
44};
45
46
47struct A {
48 void operator delete(void *, std::size_t) {}
49};
50
51
52struct B {
53 void operator delete(void *) {}
54};
55
56
57struct C {
58
59};
60
61
62int main()
63{
64 A *a = new A;
65 deleter<A>::invoke(a);
66
67 B *b = new B;
68 deleter<B>::invoke(b);
69
70 C *c = new C;
71 deleter<C>::invoke(c);
72}