【问题标题】:C++ Pseudo Destructor on Array Type数组类型上的 C++ 伪析构函数
【发布时间】:2014-10-10 20:38:27
【问题描述】:

我正在使用std::aligned_storage,需要在aligned_storage 中存储数组类型。以下代码在 Visual cpp 中编译,但不是 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++,我应该如何手动正确地销毁数组类型?

【问题讨论】:

  • 将您的模板专门用于数组类型?
  • 提示:union{T v;} store; 还定义了一个适合存储 T 的方法,而无需调用任何讨厌的 ctor。
  • @Deduplicator 这个例子被大大简化了,有充分的理由在 c++ 中更喜欢aligned_storage 而不是联合。
  • @MattBierner:请说出一个在这种情况下更喜欢std::aligned_storage 而不是union 的充分理由。 (感觉就像你减少了很多测试用例,当然。)

标签: c++ templates c++11 stl


【解决方案1】:

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

  1. 在点. 或箭头-&gt; 运算符之后使用伪析构函数名称 表示由type-name 表示的非类类型的析构函数em> 或 decltype-specifier。 ...
  2. 点运算符的左侧应为标量类型。箭头运算符的左侧应为指向标量类型的指针。 ...

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

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));
    }
};

【讨论】:

  • 看起来不错。是原始代码无效还是 Clang 错误?
  • @MattBierner 代码格式错误。我在答案中做了一个简短的解释。
  • 似乎应该有一个标准库解决方案来解决这个问题。 C++11 或 C++14 中是否已经提供了类似于 std::destroy&lt;T&gt;() 的内容?
  • 我很困惑。 std::vector 是否有数组重载来处理这个问题?
猜你喜欢
  • 2019-08-08
  • 1970-01-01
  • 2014-05-27
  • 2011-09-01
  • 2013-07-28
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
相关资源
最近更新 更多