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

7
假设我有一个类型为std::vector::iterator的变量x,它是通过放置new(placement new)分配的(出于其他原因),例如:
new((void*)&x) std::vector<int>::iterator();

如何以符合标准的方式调用对象的析构函数?可以使用以下代码实现:
x.std::vector<int>::iterator::~iterator();

例如在gcc中工作,但在clang中不起作用。

假设 x 是 C struct 的一个成员,例如 struct A { std::vector<int>::iterator x; ... } 并且你有一个 struct A* 来初始化和销毁它。(在我的情况下,它是 Python 扩展类实例。) - robertwb
1个回答

1
所有标准(和符合标准的)迭代器都遵循Iterator概念,该概念要求是Destructible。因此,只需像在任何其他使用放置 new 构造的(非平凡)类型中一样调用迭代器的析构函数即可。请保留HTML标签。
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;
}

实时示例(GCC)

更新:看起来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;
}

实时示例(clang)

更新:嗯,这是clang中的一个错误:http://llvm.org/bugs/show_bug.cgi?id=12350请参见Dieter Lücking的评论。


对于这一混乱,我非常抱歉,特别是对OP表示歉意(链接)


这不是析构函数声明,而是析构函数调用。(你之前的回答更好)。实际上这是clang的一个bug:http://llvm.org/bugs/show_bug.cgi?id=12350 - user2249683
@DieterLücking 您是正确的。请不要像我一样。 - Mark Garcia
或许这不是一个 bug,而是 clang 检测到其他编译器无法看到的 C++ 错误?https://bugzilla.mozilla.org/show_bug.cgi?id=623303 - Sturla Molden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接