The following code (which compiles and executes properly, doing what I want) is a minimal example of an oddity I experienced while writing a class to store properties of various types that needed the ability to delete pointers when it no longer knows their types. My solution was to make a Deleter class with a templated function that could have its address taken and stored to delete a specific type. I don't understand why this code works, specifically:
- Why doesn't it hit the assert?
- Why/how does it require/use the (seemingly) unrelated specialization?
Code:
#include <iostream>
#include <string>
#include <cassert>
#include <locale> //Just here as an unused class to specialize
using namespace std;
typedef void(*void_voidptr_func_t)(void*);
class ClassWithDestructor {
public:
~ClassWithDestructor() {
cout << "Destroyed\n";
}
};
class Deleter {
public:
template <class T>
static void Delete (T* ptr) {
assert(0);
}
//locale here can be any class
//it doesn't matter what class it is
//but if this specialization doesn't exist
//compile fails
template <class locale>
static void Delete(void* ptr) {
delete (locale*)ptr;
}
};
void* void_ptr_to_T = NULL;
void_voidptr_func_t T_delete_function = NULL;
template<class T>
void A() {
T* t = new T;
void_ptr_to_T = (void*)t;
T_delete_function = &Deleter::Delete<T>;
}
int main(int argc, char** argv) {
A<ClassWithDestructor>();
T_delete_function(void_ptr_to_T);
}
Compiler: MSVC++ 2010, Microsoft Extensions Disabled
Output:
Destroyed