2014-02-18 1 views
7

다른 위치에 배치 된 새로운 유형의 std :: vector :: iterator 변수 x가 있다고 가정합니다.C++에서 중첩 된 템플릿 클래스 소멸자를 호출합니다.

new((void*)&x) std::vector<int>::iterator(); 

표준을 준수하는 방식으로 소멸자를 호출하는 방법은 무엇입니까? Doing

x.std::vector<int>::iterator::~iterator(); 

예를 들어 gcc에서는 작동하지만 clang에서는 작동하지 않습니다.

+3

도대체 x는 무엇입니까? –

+0

x를 C 구조체의 멤버로 간주합니다. 'struct A {std :: vector :: iterator x; ...}'초기화하고 파괴하기 위해'struct A *'를 받는다. (제 경우에는 Python 확장 클래스 인스턴스입니다.) – robertwb

답변

1

모든 표준 (및 표준 호환) 반복기는 이어야하며 Iterator concept을 따릅니다. 따라서 새로운 배치로 생성 된 다른 (자명하지 않은) 유형 에서처럼 반복기의 소멸자를 호출하는 것으로 충분합니다. 당신이 포인터를 통해 반복자를 참조하는 경우, 당신은 -> 연산자를 사용해야

x.~iterator_type(); // where x is an iterator 

참고 :

#include <vector> 


int main() { 
    auto buffer = new char[sizeof(std::vector<int>::iterator)]; 

    auto iterator = new((void*)buffer) std::vector<int>::iterator(); 
    iterator->std::vector<int>::iterator::~iterator(); 

    delete[] buffer; 
} 

LIVE EXAMPLE (GCC)

UPDATE : 연타 컴파일 몇 가지 문제가 보인다 표준 호환 코드를 사용합니다. 당신은 소멸자를 호출 할 때 간접를 제공하여 이에 대한 해결 방법을 만들 수 있습니다

#include <vector> 

template<typename T> 
void call_destructor(T* x) { 
    x->~T(); 
} 

int main() { 
    auto buffer = new char[sizeof(std::vector<int>::iterator)]; 

    auto iterator = new((void*)buffer) std::vector<int>::iterator(); 
    //iterator->std::vector<int>::iterator::~iterator(); 
    call_destructor(iterator); 

    delete[] buffer; 
} 

LIVE EXAMPLE (clang)

UPDATE : 야아합니다. 그것은 clang의 버그입니다 : http://llvm.org/bugs/show_bug.cgi?id=12350. See Dieter Lücking's comment.


나는 this mess을 위해, 특히 영업 이익, 여러분 모두에게 매우 죄송합니다.

+0

소멸자 선언은 아니지만 소멸자 호출입니다. (당신의 대답은 이전보다 좋았습니다). 실제로 clang 버그입니다. http://llvm.org/bugs/show_bug.cgi?id=12350 –

+0

@ DieterLücking 네 말이 맞아. 제발 저처럼 굴지 마세요. –

+0

아니면 버그가 아니지만 다른 컴파일러에서 볼 수있는 C++ 오류를 감지하지 못했습니까? https://bugzilla.mozilla.org/show_bug.cgi?id=623303 –