问题
I'm trying to call explicit constructor/destructor with traits in templatized function.
template <int i>
struct Traits
{
};
template <>
struct Traits<1>
{
typedef Foo type_t;
};
template <>
struct Traits<2>
{
typedef Bar type_t;
};
template <class Traits>
void DoSomething(void* p_in)
{
typename Traits::type_t* p = reinterpret_cast<typename Traits::type_t*>(p_in);
// this works.
new (p) typename Traits::type_t;
// neither of following two does work.
p->~typename Traits::type_t();
p->typename ~Traits::type_t();
}
// call
void* p_in = malloc(BIG_ENOUGH);
DoSomething<Traits<1> >(p_in);
free(p_in);
In GCC 4.4.3 with -ansi flag, calling explicit constructor works fine. However, calling explicit destructor does not work, giving following error:
error: expected identifier before 'typename'
error: expected ';' before 'typename'
I suspect some parentheses or keyword is missing.
UPDATE
People ask about why I am doing this... Yes, as expected, I want to use memory pool, and give two functions to clients. Internally it uses a static pointer to the memory pool for malloc/free.
template<class Traits>
typename Traits::type_t* memory_pool_new();
template<class Traits>
void memory_pool_delete();
Of course this approach has limitations... like only default constructor can be used. I thought about overloading new, but it requires overloading new of all type_t's, and it will change the behavior of existing codes.
回答1:
The MSDN site gives this example:
To explicitly call the destructor for an object,
s
, of classString
, use one of the following statements:s.String::~String(); // Nonvirtual call ps->String::~String(); // Nonvirtual call s.~String(); // Virtual call ps->~String(); // Virtual call
So you could try to add a typedef and mimic the above with:
typedef typename Traits::type_t TraitsType;
// we now have that p is of TraitsType*
p->TraitsType::~TraitsType(); // nonvirtual call
p->~TraitsType(); // virtual call
回答2:
Personally, I'd use a local typedef since typename Traits::type_t
is a bit of a mouthful. If you don't want to do that, then the destructor syntax is:
p->Traits::type_t::~type_t();
By the way, there's no need to mess around with reinterpret_cast
; you can simply initialise the typed pointer from the new expression:
typename Traits::type_t* p = new (p_in) typename Traits::type_t;
来源:https://stackoverflow.com/questions/11988209/call-explicit-constructor-destructor-with-traits-in-templatized-function