数组类型上的 C++ 伪析构函数 [英] C++ Pseudo Destructor on Array Type

查看:48
本文介绍了数组类型上的 C++ 伪析构函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 std::aligned_storage 并且需要在 aligned_storage 中存储数组类型.以下代码在 Visual cpp 中编译,但不在 Clang 中编译.

template 结构体{类型名称 std::aligned_storage::value>::type 存储;模板 Foo(Args&&... args){new (&store) T { std::forward(args)... };}无效释放(){reinterpret_cast<T*>(&store)->~T();//这里的 Clang 问题}};Fooa2);//好的Foob(1, 2, 3);//叮当错误

具体的错误是:

 非标量类型T"(又名int [3]")的表达式不能用在伪析构函数表达式中

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

解决方案

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

<块引用>

  1. 在点<​​code>.或箭头->后使用伪析构函数名称表示非-由 type-namedecltype-specifier 表示的类类型....
  2. 点运算符的左侧应为标量类型.箭头运算符的左侧应为指向标量类型的指针....

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

template 无效销毁(T& t){t.~T();}模板 <typename T, std::size_t N>void destroy(T (&t)[N]){for (auto i = N; i-- > 0;) {销毁(t[i]);}}模板 结构体{类型名称 std::aligned_storage::value>::type 存储;模板 Foo(Args&&... args){new (&store) T { std::forward(args)... };}无效释放(){销毁(reinterpret_cast<T&>(商店));}};

I'm using std::aligned_storage and need to store array types in the aligned_storage. The following code compiles in visual cpp but not 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

The specific error is:

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

Is this valid C++ and how should I properly destruct array types manually?

解决方案

The program is ill-formed, you may not use a pseudo destructor call on an array type. §5.2.4 Pseudo destructor call [expr.pseudo]:

  1. The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the non-class type denoted by type-name or decltype-specifier. ...
  2. The left-hand side of the dot operator shall be of scalar type. The left-hand side of the arrow operator shall be of pointer to scalar type. ...

An overloaded function can handle the destruction appropriately for both array and non-array types by manually destroying each of the array elements (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));
    }
};

这篇关于数组类型上的 C++ 伪析构函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆