【问题标题】:C++ invoke nested template class destructorC++ 调用嵌套模板类析构函数
【发布时间】:2023-03-23 09:06:01
【问题描述】:

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

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

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

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

例如在 gcc 中有效,但在 clang 中无效。

【问题讨论】:

  • 认为 x 是 C 结构的成员,例如struct A { std::vector&lt;int&gt;::iterator x; ... } 给你一个 struct A* 来初始化和销毁​​。 (在我的例子中,它是一个 Python 扩展类实例。)

标签: c++ templates destructor nested-class


【解决方案1】:

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

x.~iterator_type();   // where x is an iterator

注意,如果通过指针引用迭代器,必须使用-&gt;操作符:

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

LIVE EXAMPLE (clang)

更新: 是的。这是 clang 中的一个错误:http://llvm.org/bugs/show_bug.cgi?id=12350See Dieter Lücking's comment.


对于this mess,我对你们所有人,尤其是对 OP 感到非常抱歉。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-07-03
  • 2016-10-07
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 2020-07-21
  • 2023-04-07
相关资源
最近更新 更多