C++ - 尽管有括号列表初始化,但不能“新建”未知大小的数组?

Posted

技术标签:

【中文标题】C++ - 尽管有括号列表初始化,但不能“新建”未知大小的数组?【英文标题】:C++ - Cannot 'new' an array on unknown size in spite of Braced-List initialization? 【发布时间】:2016-07-01 11:07:20 【问题描述】:

前言:

我没有发现有关此问题的任何信息。我发现的唯一一件事是人们动态分配数组而不提供有关所述数组大小的任何信息,例如int* p = new int[];

我的问题不同:

float arr[] 1,2,3 ;
float* p = new float[]1, 2, 3;

第一行可以编译,第二行不行:

错误 C3078 必须在新表达式中指定数组大小

我想知道:为什么编译器不像第一种情况那样评估列表初始化中的数组大小?

【问题讨论】:

std::vector<float> p = 1, 2, 3 :) 我们不喜欢这里的任意限制 - 通过让你自己的生活变得困难,你也让我们的生活变得困难! @LightnessRacesinOrbit 我刚发了一个问题。如果这让你的生活更艰难,你可以忽略我的问题。 @gedamial:如果你在寻求免费帮助时失去对抗的态度,你会在这里过得更好。 @LightnessRacesinOrbit 如果我提出了一个具体问题,而你告诉我我让你的生活变得复杂,我认为你没有理由考虑我的问题。这只是一个提示 【参考方案1】:
void* operator new[] (std::size_t size);

明确要求尺寸。您可以定义自己的运算符来获取初始化列表。

正如评论员所说,std::vector 通常是首选方法,但我猜你对语言的技术感兴趣,这就是你问的原因。

【讨论】:

通过向我展示 new 运算符的实现,您已经完美地回答了我的问题;) 我不确定这是否是一个很好的理由。即使是非数组 operator new 也需要一个大小,这是由编译器自动确定的。为什么编译器不能为 OP 的情况推断它?如果它可以通过“user-defined-parameters-placement-new”(operator new[](size_t, ...)),那么它看起来像是标准中的一个忽视?【参考方案2】:

我认为这是一个完全合理的问题,而且由于new 运算符的定义方式的性质,这是对它的限制。

以下内容确实是人为的,但如果您真的想避免明确说明动态分配的数组的大小,它可能对您有用:

template<typename T, T ... args>
T* createArray()

    return new T[sizeof...(args)]args...;

然后:

int* arr = createArray<int, 1, 2, 3>();

【讨论】:

非常感谢您向我展示了模板功能替代方案 ;)【参考方案3】:

我正在阅读 Bjarne Stroustrup 的书“Programming....” 在第 17 章第 597 页中,Bjarne 明确表示:

double* p5 = new double[] 0,1,2,3,4

在下面的段落中:“......当提供一组元素时,可以省略元素的数量。”

所以在我看来这个问题是因为编译器的错误实现,不是吗?

【讨论】:

【参考方案4】:

只是……没有。它没有语法。

你可以在那里找到一个基本原理,动态内存通常由动态长度的动态数据填充(否则,除非只是因为它很大,你为什么要使用动态分配?)因此,请求的空间很可能是很少使用的边缘情况。

【讨论】:

以上是关于C++ - 尽管有括号列表初始化,但不能“新建”未知大小的数组?的主要内容,如果未能解决你的问题,请参考以下文章

这是对大括号初始化列表的不安全使用吗?

大括号之谜:C++的列表初始化语法解析

数组未在 C++ 中使用花括号进行初始化

大括号之谜:C++的列表初始化语法解析

C++ Struct 未通过 POD 测试

尽管调用了 Firebase.initializeApp(),但 Firebase 未初始化