我一直试图区分传递给构造函数的参数是数组还是简单指针的情况。所以,我编写了这个示例代码
#include <iostream>
#include <type_traits>
using std::cout;
using std::endl;
// here I create a structure which I intend to use
// to tell arrays from non-arrays.
template<typename T>
struct TypeTraits {
static bool const IsArray = false;
};
template<typename T>
struct TypeTraits<T[]> {
static bool const IsArray = true;
};
// And here I create a container to store a pointer.
template<typename TValue>
class Ptr_container {
TValue * ptr;
public:
template<typename T>
explicit Ptr_container(T from_ptr) :
ptr (from_ptr)
{
cout << std::boolalpha;
cout << TypeTraits<T>::IsArray << endl;
cout << "Just to be sure: " << std::is_array<T>::value << endl;
}
~Ptr_container()
{
delete ptr;
}
};
int main () {
Ptr_container<int> a (new int(2));
Ptr_container<int> b (new int[2]);
return 0;
}结果是假的/假的。所以,我显然做错了什么,问题是,当使用新T和新TN分配新内存时,我应该做什么来区分这些情况?
更新:--我使用std::is_array添加了一个"arrayness“检查,但不会改变结果。在编译期间,必须有某种方法来检测“数组”,因为以下原因:boost::shared_ptr将指针作为构造函数的参数,并且它的内部结构仅使用该信息进行初始化。在boost::shared_ptr类中的某个地方,有一个结构决定如何删除shared_ptr (使用delete或delete[])指向的内存。
实际上,我正在尝试实现shared_ptr的某些部分,但我在数组识别阶段失败了。
更新2我终于弄明白了,所以我要结束这个问题。该问题的解决方案是向模板中添加另一个参数,并以如下方式初始化容器
Ptr_container<int, PointerProperty> pa (new int(4));
Ptr_container<int, ArrayProperty> pv (new int[4]);发布于 2013-12-01 23:17:01
您绝对不能区分编译时从new和new[]返回的指针。不使用模板,也不使用编译器钩子的标准类型特征,也不使用任何其他技术。
这样做的原因应该是显而易见的;如果不是,请考虑以下代码:(事情不是这样工作的;我只是效仿您的例子。)
int * p = nullptr;
if (rand() % 2 == 0)
p = new int;
else
p = new int [42];
print_is_array (p); // Assume this does the detection and prints something.您(和编译器)如何在编译时知道p将使用new还是new[]分配?
此外,您所称的“数组”更恰当地称为“向量”(不能与std::vector混淆)。数组具有一些编译时属性(如大小),即使您碰巧在其中构造多个对象(例如使用new[]),运行时分配的内存块也不会这样做。
并且,将T的数组(一个真正的、适当的、编译时的数组)传递到接受T *s的函数中,将“衰减”类型,并失去“数组”。这里我指的是您定义构造函数的方式,即它采用了一个T *。
如果您想知道如何在编译时检测(适当的)数组,请看一下std::is_array<T>模板在<type_traits>头中的实现。
编辑:顺便说一下,当我说(适当的)数组时,这就是我的意思:
int a [42];不是这样的:
int * p = new int [42];这是两种不同的类型,但第一种可以“衰变”,并被隐式地转换为第二种类型。
发布于 2013-12-01 23:02:11
正如Zeta在评论中所说:
typeof (new int) == typeof (new int[]) == int *但是,如果您需要区分使用new和new[]创建的类的对象,则重载将更有意义。
https://stackoverflow.com/questions/20318272
复制相似问题