0

Given std::vector<A>::iterator and std::map<A, B>::iterator, how do I explicitly call their destructors? I do not know the actual names of these types, because the ::iterator member types are typedefs/aliases to implementation-specific classes.

I ask this question, because I am storing these iterators in an unrestricted c++ union and Visual Studio asks me to manually handle destruction. I could simply not call the destructor of the active element and assume iterators do not need clean-up, but that reeks of bad practice.

Stijn Frishert
  • 1,543
  • 1
  • 11
  • 32
  • This smells like you are doing it wrong. But I don't know what you're doing, so I can't help you do it another, perhaps better way. – rubenvb Mar 07 '17 at 11:49

3 Answers3

4

Like this:

// let iter be vector<int>::iterator to be destroyed
iter.std::vector<int>::iterator::~iterator();

I do not know the actual names of these types, because the ::iterator member types are typedefs/aliases to implementation-specific classes.

Doesn't matter. Type aliases are type names as well.


LLVM appears to have a bug with this: https://bugs.llvm.org//show_bug.cgi?id=12350

Until it is fixed, as a workaround, introduce a non-nested alias:

using iterator = std::vector<int>::iterator;
iterator it;
it.iterator::~iterator();

or refer to the type as template argument (this code is from the bug report):

template <typename T>
inline void placement_delete(T *x) 
{
   // C++ lacks placement delete, so fake it with a function
   x->~T();
}
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • @RichardCritten appears to not be a problem according to standard: `The notation for explicit call of a destructor can be used for any scalar type name` – eerorika Mar 07 '17 at 11:34
  • @StijnFrishert I think this is a clang bug. It appears to affect qualified nested type names - not type aliases. You can work around it with non-nested alias: https://godbolt.org/g/0TsBi7 – eerorika Mar 07 '17 at 11:41
  • @user2079303 thanks it does, going to ask a follow up question as it looks really strange. ... found a duplicate: http://stackoverflow.com/questions/24000710/pseudo-destructor-call-does-not-destroy-an-object – Richard Critten Mar 07 '17 at 11:43
  • @StijnFrishert I updated the answer regarding the bug. – eerorika Mar 07 '17 at 11:47
  • @user2079303 Accepted this answer, because it follows the standard and the clang bug doesn't change that. Was about to file a report, good you found one already. – Stijn Frishert Mar 07 '17 at 11:51
3
std::destroy_at(&iter);

std::destroy and friends are a C+17 feature. If your compiler lacks support it is trivial to implement yourself:

template <typename T>
void destroy_at(T* p) {
    p->~T();
}

Source.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

Most often iterator are nothing but pointer to already allocated memory. Unless the iterators are created using new

 typedef std::vector<A>::iterator VecIter;
 VecIter* iter= new VecIter;

there is no need to delete. If you are using new, then you can call delete explicitly for the iterator variable.

delete iter; 
Mrnell
  • 91
  • 4
  • I am not talking about calling delete on an iterator, but explicitly calling its destructor. https://msdn.microsoft.com/en-us/library/6t4fe76c.aspx#Anchor_3 – Stijn Frishert Mar 07 '17 at 11:32