如果向量为空, std::vector::data() 应该返回什么?

2021-12-21 00:00:00 vector c++

根据标准草案(23.3.6.4 向量数据)、data()指向底层数组且[data(), data() + size())必须是有效范围:

According to the draft standard (23.3.6.4 vector data), data() points to the underlying array and [data(), data() + size()) must be a valid range:

T* data() noexcept;
const T* data() const noexcept;

    1 Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector,
data() == &front().
    2 Complexity: Constant time

但是如果向量是空的呢?当我构造一个零大小的向量时:

But what if the vector is empty? When I construct a zero-size vector:

#include <vector>
#include <iostream>

int main() {
    const int NUM = 0*10;
    std::vector< double > v( NUM, 0.0 );
    std::cerr << "V : "<< v.data() << std::endl;
}

MSVC 2010 返回 null,但在 Linux(使用 GCC 4.2.1 和 Intel 12.1)上我得到一个非 null 地址.

MSVC 2010 returns null, but on Linux (with GCC 4.2.1 and Intel 12.1) I get a non-null address.

是否允许 vector::data() 或者它应该返回 null?例如,实现是否可以进行默认大小的初始分配并返回指向它的(非空)指针?

Is vector::data() allowed to or should it return null? Could an implementation, for example, do a default-size initial allocation and return a (non-null) pointer to it?

几个答案侧重于空范围的有效性.我完全同意.

Several answers focus on the validity of an empty-range. I fully agree there.

我真的很想看到一个很好的参考或解释:是否允许,必须返回空值或可能也返回非空?

I would really like to see a good reference or explanation for: Is it allowed to, must it return null or may it also return non-null?

推荐答案

范围的约定是[inclusive,exclusive),也就是说如果你遍历一个范围 [X,Y) 您将从概念上执行以下操作(伪代码):

The convention for ranges is [inclusive, exclusive), that is if you iterate over a range [X,Y) you will conceptually do the following (pseudo-code):

for( iterator ii = X; ii != Y; ++ii) {
...
}

这允许将空范围表示为 [X,X).此外,这个空范围为每个地址定义得很好,无论它是有效还是无效.

This permits to express an empty range as [X,X). Also this empty range is perfectly well defined for each address, no matter if it is valid or invalid.

也就是说 data() 的要求是(强调我的):

That said the requirements for data() are (emphasis mine):

23.3.6.4 [vector.data]

T* data() noexcept;

T* data() noexcept;

const T* data() const noexcept;

const T* data() const noexcept;

返回:一个指针,使得[data(),data() + size()) 是一个有效范围.为一个非空向量,data() == &front().

Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector, data() == &front().

在我看来,唯一的无条件保证是 [data(),data() + size()) 应该是一个有效范围.对于 size() == 0 成员函数 data() 可以返回任何值,范围将是一个有效的空范围.因此,我会说如果size()为零,则允许实现返回非空指针.

It seems to me that the only unconditional guarantee is that [data(),data() + size()) should be a valid range. For size() == 0 the member function data() may return any value and the range will be a valid empty range. Therefore I would say that an implementation is allowed to return a non-null pointer if size() is zero.

相关文章