Call explicit constructor/destructor with traits in templatized function

跟風遠走 提交于 2021-01-28 19:59:51

问题


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 class String, 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!