Question

Suppose I have a variable x of type std::vector::iterator that was allocated (for other reasons) with placement new, e.g.

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

How does one call its destructor in a standards compliant way? Doing

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

for example works in gcc but not clang.

Was it helpful?

Solution

All standard (and standard-compliant) iterators follow the Iterator concept, which is required to be Destructible. Thus, it suffice to simply call the iterator's destructor just as you would in any other (non-trivial) types constructed with placement new.

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

Note that if you refer to the iterator through a pointer, you must use the -> operator:

#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: It seems that Clang has some problems compiling the (I presume standards-compliant) code. You can make a work-around on this by providing an indirection when calling the destructor:

#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: Yah. It's a bug in clang: http://llvm.org/bugs/show_bug.cgi?id=12350. See Dieter Lücking's comment.


I'm very sorry to all of you, especially to the OP, for this mess.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top