所以我构建了我打算使用的类 std::aligned_storage
为“Variant”类存储最多 16 个字节的不同类型。理论上它应该能够存储任何 POD 类型和常见容器,例如 std::string
和 std::map
.
我查看了此处找到的代码示例,它似乎正是为我所寻找的而制作的:http://en.cppreference.com/w/cpp/types/aligned_storage
我的版本,基本上:
class Variant {
public:
Variant() { /* construct */ }
Variant(std::map<int,int> v) {
new(&m_data) std::map<int,int>(v); // construct std::map<int,int> at &m_data
m_type = TYPE_MAP;
}
~Variant() {
if (m_type == TYPE_MAP) {
// cool, now destruct..?
reinterpret_cast<std::map<int, int>*>(&m_data)->~/*???????????????*/();
}
}
private:
// type of object in m_data
enum Type m_type;
// chunk of space for allocating to
std::aligned_storage<16, std::alignment_of<std::max_align_t>::value>::type m_data;
};
我的问题来自破坏。正如您在 /*???????????????*/
看到的那样, 我不确定用什么来代替 ~T()
在 cppreference.com 示例中:
reinterpret_cast<const T*>(data+pos)->~T(); // I did the same thing except I know what T is, is that a problem is it?
在我看来,我正在做完全相同的事情,无视模板匿名性。问题是,std::map
没有任何 std::map::~map()
析构方法,只有一个std::map::~_Tree
,这显然不适合直接使用。因此,在 cppreference.com 示例代码中,~T()
会是什么?如果 T
正在打电话是一个std::map<int,int>
,以及我为 std::aligned_storage
中具有已知类型的对象调用析构函数的正确方法是什么? ?还是我把事情复杂化了并且是clear()
这些 STL 容器中的方法保证相当于完全破坏?
或者,有没有更简单的方法解决这个问题?因为我可能一直误解了我对 std::aligned_storage
的预期用途。 .
最佳答案
听起来您已经阅读了定义了 std::map
的头文件,并认为 std::map
没有析构函数,因为您找不到声明一个析构函数。
但是,在 C++ 中,没有声明析构函数的类型将有一个由编译器隐式声明的析构函数。这个隐式析构函数将调用基类和非静态成员的析构函数。听起来您的库实现中的 std::map
是 _Tree
上的薄层。因此,破坏 map 所需要做的就是破坏树。因此,编译器的默认析构函数可以解决问题。
允许在你的情况下编写->~map()
,它会调用隐式定义的析构函数, map 将被正确销毁。您也可以将此语法用于标量类型,例如 int
(但出于某种原因不能用于数组)。
关于c++ - 如何销毁通过 'Placement New' 构造的无析构函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42308304/