2012-08-16 56 views
1

我试图在模板化函数中调用具有特征的显式构造函数/析构函数。在模板化函数中调用具有特征的显式构造函数/析构函数

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); 

在具有-ansi标志的GCC 4.4.3中,调用显式构造函数可以正常工作。但是,调用显式析构函数不起作用,给出以下错误:

error: expected identifier before 'typename' 
error: expected ';' before 'typename' 

我怀疑是缺少一些括号或关键字。

UPDATE

人们问我为什么要这么做?是的,正如预期的,我要使用的内存池,并给两个功能给客户。在内部它使用一个静态指针指向内存池malloc/free。

template<class Traits> 
typename Traits::type_t* memory_pool_new(); 
template<class Traits> 
void memory_pool_delete(); 

当然这种方法有局限性...就像只有默认的构造函数可以使用。我想过要重载new,但它需要重载所有type_t的new,它会改变现有代码的行为。

+0

你为什么要调用析构函数? – TemplateRex 2012-08-16 13:32:34

+0

你究竟想做什么?试图调用哪个析构函数? – 2012-08-16 13:34:32

回答

1

MSDN网站给出了这样的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 

所以,你可以尝试添加一个typedef和模仿上面:

typedef typename Traits::type_t TraitsType; 

// we now have that p is of TraitsType* 
p->TraitsType::~TraitsType(); // nonvirtual call 
p->~TraitsType();    // virtual call 
+0

谢谢 - 它的作品就像一个魅力!我读了MSDN,但想不到添加typedef。 – xosp7tom 2012-08-16 13:39:55

+0

@ xosp7tom很高兴工作! – TemplateRex 2012-08-16 13:42:23

+0

如果他使用某种内存池并使用就地构造,则明确调用析构函数可能会有用。 – Cubic 2012-08-16 13:44:18

0

就个人而言,我会使用一个本地的typedef自typename Traits::type_t是一口一口。如果你不想这样做,那么析构函数语法是:

p->Traits::type_t::~type_t(); 

顺便说一句,有没有必要与reinterpret_cast浪费时间;你可以简单地从新的表达式初始化输入的指针:

typename Traits::type_t* p = new (p_in) typename Traits::type_t; 
相关问题