2012-08-16 3 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(); 

물론이 접근 방식에는 제한이 있습니다 ... 기본 생성자 만 사용할 수 있습니다. 나는 overloading new에 대해 생각했지만, 모든 type_t의 새로운 오버로딩을 필요로하고, 기존 코드의 동작을 바꿀 것이다.

+0

왜 소멸자를 호출합니까 ?? – TemplateRex

+0

실제로 무엇을하려고합니까? 어떤 소멸자를 부르려고? –

답변

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

+0

@ xosp7tom 다행입니다! – TemplateRex

+0

그는 일종의 메모리 풀을 사용하고 내부 생성을 사용하는 경우 소멸자를 명시 적으로 호출하는 것이 유용 할 수 있습니다. – Cubic

0

내가 typename Traits::type_t 때문에 로컬 형식 정의를 사용하십시오 약간의 입가심이 있습니다. 당신이 그렇게하지 않는다면, 소멸자 구문은 다음과 같습니다

그런데
p->Traits::type_t::~type_t(); 

, reinterpret_cast와 주위 엉망 필요가 없습니다; 새 표현식에서 입력 된 포인터를 간단히 초기화 할 수 있습니다.

typename Traits::type_t* p = new (p_in) typename Traits::type_t;