正确转发到动态分配数组的特化

Correctly forward to specializations for dynamically allocated arrays

我了解到您可以使用 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 pointer\n"; 
        delete _Ptr;
    }
};

template<class _Ty>
struct OP<_Ty[]>
{
    void operator()(_Ty *_Ptr) const noexcept
    {
        std::cout << "dynamically allocated array\n"; 
        delete[] _Ptr;
    }
};

template<typename T>
void f1(T *arg)
{
   OP<T>()(arg); 
}


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

above 打印

single pointer

single pointer

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

你的两个电话属于同一类型。我们可以用一个简单的程序来验证这一点:

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

在[expr.new]中的标准中注明:

When the allocated object is an array (that is, the noptr-new-declarator syntax is used or the new-type-id or type-id denotes an array type), the new-expression yields a pointer to the initial element (if any) of the array. [ Note: both new int and new int[10] have type int* and the type of new int[i][10] is int (*)[10] —end note ] The attribute-specifier-seq in a noptr-new-declarator appertains to the associated array type.

因此无法根据类型区分指向单个元素的指针和指向数组的指针。你可以传递一些额外的标签,比如:

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