C++ C++;调用嵌套模板类析构函数
假设我有一个std::vector::iterator类型的变量x,该变量被分配(出于其他原因)为placement new,例如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
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扩展类实例。)