是否可以在C++中动态创建一个常量大小的数组?

Arm*_*yan 17 c++ arrays new-operator

首先,我想向大家保证,我出于好奇而问这个问题.我的意思是,不要告诉我,如果我需要这个,那么我的设计有问题,因为我不需要在实际代码中.希望我说服你:)现在问题:

对于大多数类型T我们可以写

T* p = new T;
Run Code Online (Sandbox Code Playgroud)

现在如果T是数组类型怎么办?

int (*p)[3] =  new ???; //pointer to array of 3 = new ???
Run Code Online (Sandbox Code Playgroud)

我试过这个:

typedef int arr[3];
arr* p = new arr;
Run Code Online (Sandbox Code Playgroud)

但这不起作用.

是否有任何有效的语法或在C++中是不可能的.如果不可能,为什么呢?谢谢

编辑:我猜我不够清楚.我希望能够在这种情况下使用它:

void f(int(&)[3]);
int (*p)[3] = new ???;
f(*p);
Run Code Online (Sandbox Code Playgroud)

fre*_*low 11

要从中获取指向数组的指针new,必须动态分配二维数组:

int (*p)[3] = new int[1][3];
Run Code Online (Sandbox Code Playgroud)


Ste*_*sop 10

你不能这样做的原因是new int[3]已经完全分配了你想要的东西,一个类型的对象int[3].只是new-expression 返回的是指向其第一个元素的指针.5.3.4/1:

如果实体是非数组对象,则new-expression返回指向所创建对象的指针.如果它是一个数组,则new-expression返回一个指向数组初始元素的指针.

返回指向第一个元素的指针是允许在3运行时才知道的,因此我认为通过提前知道它,你已经超过了你没有使用的灵活性.

我想解决这个问题的方法是将reinterpret_cast重新设置为你想要的指针类型(不一定是可移植的),或者分配一个包含int[3](并使用指向其数据成员的指针)的结构.

[编辑:呃,是的,或FredOverflow的想法,既没有劣势,但需要使用delete[]而不是delete.]

我猜的寓意是,如果你写一个天真地分配一些未知类型的模板Tnew,那么模板时不会有人经过一个数组类型的工作T.你将它分配给错误的指针类型,如果你修复它(可能有auto),你将错误地删除它.

编辑回答j_kubik的问题:

这是区分数组和非数组类型的一种方法.如果您编写这样的函数,它返回一个包含指针的对象并且能够正确删除它,那么您对任何类型T都有一个通用的新/删除.

#include <iostream>

template <typename T>
void make_thing_helper(T *) {
    std::cout << "plain version\n";
}

template <typename T, int N>
void make_thing_helper(T (*)[N]) {
    std::cout << "array version\n";
}

template <typename T>
void make_thing() {
    make_thing_helper((T*)0);
}

int main() {
    typedef int T1;
    typedef int T2[3];
    make_thing<T1>();
    make_thing<T2>();
}
Run Code Online (Sandbox Code Playgroud)