2012-08-16 57 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; 
相關問題