为什么ISO C++禁止返回数组?

9

我没有看到任何逻辑原因。我的意思是,您可以通过使用包含数组成员的结构来轻松满足要求,例如:

template <size_t n>
struct arr { int d[n]; };

auto fnReturningArray()
{
    return arr<3>{0, 1, 2};
};

如果你先访问结构体成员“d”,那么使用返回指向该数组的指针将与直接返回数组完全相同,只有一个小差异。标准库自身已经通过“std::array”类型添加了类似的功能。因此看起来实现是可能的。那么为什么ISO C++禁止这种操作呢?也许是为了保持对旧代码的兼容性(但我很难相信这是原因,因为其他新添加的特性早已过时,就像“auto”关键字的新含义一样)。


7
因为数组不能被复制。 - Columbo
3
数组不可复制或赋值,因此您无法通过值返回或传递它们。至于为什么会这样,那是一个好问题。 - juanchopanza
10
@Nikolay 不行,因为无论用哪种语言都不是这样的。 - molbdnilo
12
@Nikolay: 谁告诉你“数组和指针实际上是一样的”?他们说错了。 - Lightness Races in Orbit
2
@Nikolay:是的,你可以。它是一个指针。你无法确定它所指向的内存块有多大。 - Lightness Races in Orbit
显示剩余8条评论
2个回答

2

除了标准不允许外,还有历史原因可以解释,问题在于语法

想象一下如果允许这样做:你如何区分整个数组的命名、数组地址和单个元素的命名:

auto fnReturningArray()
{
    int a[3] = {0, 1, 2};
    return a;       // what is meant here ?  the address of the array ? or the whole array ?  
};

如果更改现有规则的含义(例如规定a将成为整个数组),您将面临遗留代码的巨大问题。

2
你可能会有一个规则,规定你返回 int[3],因为这是 a 的类型。如果语言允许返回数组,那么这就是完美的解决方案。但你在这里使用了循环论证。 - juanchopanza
9
很简单:a是一个数组,所以意味着你要返回一个数组。如果你想要指向第一个元素的指针,你应该写成&a[0]。虽然这不是C++的运作方式,但这是一种非常合理的语言设计。 - user743382
7
我并不是在说现在将它添加到C++是有意义的,只是如果从一开始就是C++(甚至C)的设计方式,那么这样做就有意义了。 - user743382
1
@Jako:这不是“非此即彼”的问题;兼容性有不同的程度,而这将是一个大问题。 - Lightness Races in Orbit
2
如果允许返回数组,那么可以对其进行哪些操作呢?当禁止foo=bar;时,允许int foo[3], bar[3]; foo=funcReturningInt3Array();似乎很奇怪。如果允许int *moo; moo=funcReturningInt3Array();,那么什么决定了数组的生命周期呢? - supercat
显示剩余7条评论

0

我认为答案有两个方面:

  1. 与C的兼容性。C不是这样工作的。为什么?不知道。从各个方面来看,C从一开始就不是非常合乎逻辑。

  2. C++更喜欢库特性而不是语言特性。由于C++98是第一个标准,它大多数基础都是从C中复制过来的(参见第1点),这在第一个主要修订版C++11中得到了纠正,引入了库类型std::array,作为一个纯粹的库特性,解决了所有C风格数组所涉及的可怕怪癖。

总之:即使对于数组来说,拥有适当的值语义可能是有意义的,但它永远不会发生,因为明显的缺陷可以通过不使语言比它已经复杂的更复杂来解决。摆脱遗留和向后兼容性非常困难,因此当前的std::array选项确实是您想要的。使用它。它很简单。你会喜欢它。很多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接