是否可以动态地创建常量大小的C ++数组? [英] Is it possible to dynamically create an array of constant size in C++?

查看:126
本文介绍了是否可以动态地创建常量大小的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 type int[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 of delete.]

I guess the moral is, if you write templates that naively allocate some unknown type T with new, then the template won't work when someone passes an array type as T. You'll be assigning it to the wrong pointer type, and if you fix that (perhaps with auto), 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆