正确转发到动态分配的阵列的专用化

Correctly forward to specializations for dynamically allocated arrays

本文关键字:阵列 专用 动态分配 转发      更新时间:2023-10-16

我了解到您可以使用以下T[]专门用于动态分配的数组:

template<typename T>
class C {}; 
template<typename T>
class C<T[]> {}; 

现在,在尝试使用此类机器时,我似乎无法编写此功能(在内层使用它,例如在函数模板中

):
#include <iostream>
template<class _Ty>
struct OP
{   
    void operator()(_Ty *_Ptr) const noexcept
    {   
        std::cout << "single pointern"; 
        delete _Ptr;
    }
};
template<class _Ty>
struct OP<_Ty[]>
{
    void operator()(_Ty *_Ptr) const noexcept
    {
        std::cout << "dynamically allocated arrayn"; 
        delete[] _Ptr;
    }
};
template<typename T>
void f1(T *arg)
{
   OP<T>()(arg); 
}

int main()
{
     f1(new int(3));  
     f1(new int[(3)]);  
}

以上打印

单指针

单指针

当很明显第二次调用是用数组完成的时。我该如何解决这个问题,我做错了什么?

您的两个调用属于同一类型。我们可以通过一个简单的程序来验证这一点:

int main()
{
    static_assert(std::is_same<
        decltype(new int(3)),
        decltype(new int[(3)])
    >{}, "wat");
}

这在 [expr.new] 中的标准中有所说明:

当分配的对象是数组(即使用 noptr-new-declarator 语法或 new-type id 或 type-id 表示数组类型),new-expression 产生指向数组初始元素(如果有)的指针。 [注意:new intnew int[10]都有int*类型,new int[i][10]的类型是int (*)[10] —尾注 ] noptr-new-declarator 中的属性说明符 seq 适用于关联的数组类型。

因此,无法通过类型区分指向单个元素的指针和指向数组的指针。不过,您可以传入一些额外的标签,例如:

struct array_tag { };
struct single_tag { };
f1(new int(3), single_tag{});
f1(new int[3], array_tag{});

或者只是明确指定类型(这需要更改其他几个签名 - f1必须采用T,而不是T*等):

f1(new int(3));
f1<int*>(new int(3));
f1<int[]>(new int[3]);