我了解到您可以使用 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
andnew int[10]
have typeint*
and the type ofnew int[i][10]
isint (*)[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]);
关于c++ - 正确转发到动态分配数组的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29637156/