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

C++ C++;调用嵌套模板类析构函数,c++,templates,destructor,nested-class,C++,Templates,Destructor,Nested Class,假设我有一个std::vector::iterator类型的变量x,该变量被分配(出于其他原因)为placement new,例如 new((void*)&x) std::vector<int>::iterator(); new((void*)&x)std::vector::iterator(); 如何以符合标准的方式调用其析构函数?做 x.std::vector<int>::iterator::~iterator(); x.std::vector::ite

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

new((void*)&x) std::vector<int>::iterator();
new((void*)&x)std::vector::iterator();
如何以符合标准的方式调用其析构函数?做

x.std::vector<int>::iterator::~iterator();
x.std::vector::iterator::~iterator();
例如,可以在gcc中工作,但不能在clang中工作。

所有标准(和符合标准的)迭代器都遵循,这是必需的。因此,只需调用迭代器的析构函数就足够了,就像在使用新位置构造的任何其他(非平凡)类型中一样

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;
}
#包括
int main(){
自动缓冲区=新字符[sizeof(std::vector::iterator)];
自动迭代器=新((void*)缓冲区)std::vector::iterator();
迭代器->标准::向量::迭代器::~iterator();
删除[]缓冲区;
}

更新:似乎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;
}
#包括
模板
无效调用_析构函数(T*x){
x->~T();
}
int main(){
自动缓冲区=新字符[sizeof(std::vector::iterator)];
自动迭代器=新((void*)缓冲区)std::vector::iterator();
//迭代器->标准::向量::迭代器::~iterator();
调用析构函数(迭代器);
删除[]缓冲区;
}

更新:耶。这是一只叮当作响的虫子:



我对你们所有人,特别是OP,感到非常抱歉。

这不是析构函数声明,而是析构函数调用。(你的答案比以前好)。它实际上是叮当作响的虫子:@DieterLück你是对的。请不要像我一样,或者它不是一个bug,而是CLAN检测C++错误,没有其他编译器可以看到的?将X视为C结构的成员,例如“代码>结构体”:{STD::vector:迭代器X;…} /代码>,并给出了<代码> StuttA*<代码>来初始化和销毁。(在我的例子中,它是一个Python扩展类实例。)