C ++调用嵌套模板类析构函数

时间:2014-02-18 08:18:51

标签: c++ templates destructor nested-class

假设我有一个类型为std :: vector :: iterator的变量x,它被分配(出于其他原因),其中包含placement new,例如。

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

如何以符合标准的方式调用其析构函数?做

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

例如在gcc中工作但不在clang中工作。

1 个答案:

答案 0 :(得分:1)

所有标准(和标准兼容)迭代器都遵循Iterator conceptDestructible必须是LIVE EXAMPLE (GCC)。因此,只需调用迭代器的析构函数就像在使用placement new构造的任何其他(非平凡)类型中一样。

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 (clang)

更新:似乎Clang在编译(我认为符合标准的)代码时遇到了一些问题。您可以通过在调用析构函数时提供间接来解决此问题:

#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;
}

http://llvm.org/bugs/show_bug.cgi?id=12350

更新:呀。这是clang中的一个错误:See Dieter Lücking's commentthis mess


对于{{3}},我非常抱歉,尤其是对OP来说。