数组类型上的C++伪析构函数

C++ Pseudo Destructor on Array Type

本文关键字:析构函数 C++ 类型 数组      更新时间:2023-10-16

我正在使用std::aligned_storage,需要将数组类型存储在aligned_storage中。以下代码在visualcpp中编译,但不在Clang中编译。

template <typename T>
struct Foo
{
    typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type store;
    template <typename... Args>
    Foo(Args&&... args)
    {
        new (&store) T { std::forward<Args>(args)... };
    }
    void Release()
    {
        reinterpret_cast<T*>(&store)->~T(); // Clang problems here
    }
};
Foo<int> a(2); // ok
Foo<int[3]> b(1, 2, 3); // error in clang

具体错误为:

 expression of non-scalar type 'T' (aka 'int [3]') cannot be used in a pseudo-destructor expression

这是有效的C++吗?我应该如何手动正确地销毁数组类型?

程序格式错误,不能对数组类型使用伪析构函数调用。§5.2.4伪析构函数调用[expr.Pseudo]:

  1. 在点.或箭头->运算符之后使用伪析构函数名称表示由类型名称ecltype说明符所表示的非类类型的析构函数
  2. 点运算符的左侧应为标量类型。箭头运算符的左侧应为指针到标量类型

重载函数可以通过手动销毁每个数组元素来适当地处理数组和非数组类型的销毁(实时代码):

template <typename T>
void destroy(T& t)
{
    t.~T();
}
template <typename T, std::size_t N>
void destroy(T (&t)[N])
{
    for (auto i = N; i-- > 0;) {
        destroy(t[i]);
    }
}
template <typename T>
struct Foo
{
    typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type store;
    template <typename... Args>
    Foo(Args&&... args)
    {
        new (&store) T { std::forward<Args>(args)... };
    }
    void Release()
    {
        destroy(reinterpret_cast<T&>(store));
    }
};