是否可以动态地创建常量大小的C ++数组? [英] Is it possible to dynamically create an array of constant size in C++?
问题描述
首先,我想向你保证一切,我问这个问题是出于好奇。我的意思是,不要告诉我,如果我需要这个,然后我的设计有问题,因为我不需要这在现实code执行。希望我说服你现在:)的问题:
对于大多数类型难道我们可以写
T * p =新笔;
现在如果T是数组类型?
INT(* P)[3] =新???; //指针指向3 =新数组?
我试过这样:
的typedef INT ARR [3];
ARR * P =新的编曲;
但是,这并不正常工作。
对此有任何有效的语法或在C是不可能++。如果它是不可能的,那么为什么呢?谢谢
的 修改的:我猜测我是不太清楚。我希望能够在这种情况下使用它:
无效F(INT(安培)[3]);
INT(* P)[3] =新???;
F(* P);
您不能这样做的原因是,新INT [3]
已分配正是你希望,类型的对象 INT [3]
。这只是什么新的-EX pression的返回的,是一个指向它的第一个元素。 5.3.4 / 1:
如果该实体是一个非阵列对象,
新-EX pression返回一个指针
对象创建。如果它是一个
阵,新-EX pression返回
指针的初始元素
数组。
块引用>返回一个指向第一个元素是什么让
3
是未知的,直到运行时,所以我想通过知道它在前进,你绊倒的灵活性你没有使用。我想解决这个问题的办法是reinter pret_cast回到你想要的(不一定便携式)的指针类型,或分配含有一个结构的
INT [3]
(及使用一个指针到其数据成员)。而不是
删除
]我猜的寓意是,如果你写一个天真地分配一些未知类型
T
与新
,然后模板当有人传递一个数组类型为T
模板将不起作用。你将它分配给了错误的指针类型,如果你解决这个问题(也许汽车
),你会被错误删除。编辑在回答j_kubik的问题:
下面的阵列和非数组类型来区分的一种方式。如果你写这样的功能,即返回包含指针,能够正确地将其删除一个对象,那么你有一个通用的新/删除任何类型T。
的#include<&iostream的GT;模板< typename的T>
无效make_thing_helper(T *){
性病::法院LT&;< 普通版\\ n;
}模板< typename的T,INT N'GT;
无效make_thing_helper(T(*)[N]){
性病::法院LT&;< 阵列版\\ n;
}模板< typename的T>
无效make_thing(){
make_thing_helper((T *)0);
}诠释主(){
的typedef INT T1;
typedef的诠释T2 [3];
make_thing< T1>();
make_thing< T2>();
}First of all, I want to reassure you all that I am asking this question out of curiosity. I mean, don't tell me that if I need this then my design has problems because I don't need this in real code. Hope I convinced you :) Now to the question:
For most types T we can write
T* p = new T;
now what if T is an array type?
int (*p)[3] = new ???; //pointer to array of 3 = new ???
I tried this:
typedef int arr[3]; arr* p = new arr;
but this doesn't work.
Is there any valid syntax for this or it is impossible in C++. If it is impossible, then why? Thanks
Edit: i am guessing I wasn't clear enough. I want to be able to use it in this situation:
void f(int(&)[3]); int (*p)[3] = new ???; f(*p);
解决方案The reason you can't do it is that
new int[3]
already allocates exactly what you want, an object of typeint[3]
. It's just that what the new-expression returns, is a pointer to its first element. 5.3.4/1:If the entity is a non-array object, the new-expression returns a pointer to the object created. If it is an array, the new-expression returns a pointer to the initial element of the array.
Returning a pointer to the first element is what allows the
3
to be unknown until runtime, so I suppose that by knowing it in advance, you've tripped over flexibility that you aren't using.I guess the ways around this are to reinterpret_cast back to the pointer type you want (not necessarily portable), or to allocate a struct containing an
int[3]
(and use a pointer to its data member).[Edit: er, yeah, or FredOverflow's idea, which has neither disadvantage, but requires use of
delete[]
instead ofdelete
.]I guess the moral is, if you write templates that naively allocate some unknown type
T
withnew
, then the template won't work when someone passes an array type asT
. You'll be assigning it to the wrong pointer type, and if you fix that (perhaps withauto
), you'll be deleting it wrongly.Edit in answer to j_kubik's question:
Here's one way to distinguish between array and non-array types. If you write a function like this, that returns an object that holds the pointer and is capable of correctly deleting it, then you have a generic new/delete for any type 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>(); }
这篇关于是否可以动态地创建常量大小的C ++数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!