[英]How to initialize std::vector of std:pair of fixed length with default values?
Assuming a struct containing a std::vector with items of type std::pair. 假设一个包含std :: vector且结构类型为std :: pair的结构。
struct block {
std::vector<std::pair<key_t, value_t>> items;
block(const Data& d) : items()
{
items = std::vector<std::pair<key_t, value_t>>(d.size_);
}
};
Later in the code, I assign a value to the vector at position 0: 在代码的后面,我为位置0的向量分配了一个值:
block<key_t, value_t> b(*this);
std::pair<key_t, value_t> item = std::pair<key_t, value_t>(k, v);
b.items[0] = item;
Later in the code, I want to iterate over the vector and expect &bucket_item != NULL
to be true only at position 0, because I only assigned a value at this position. 在代码的稍后部分,我想遍历向量,并期望
&bucket_item != NULL
仅在位置0处为true,因为我仅在此位置分配了一个值。 In fact, &bucket_item != NULL
is always true. 实际上,
&bucket_item != NULL
始终为true。
for (std::pair<key_t, value_t> item : b.items)
{
if (&item != NULL)
{
...
}
}
I am not able to initialize the vector with NULL values like so: 我无法使用NULL值来初始化矢量,如下所示:
items = std::vector<std::pair<key_t, value_t>>(d.size_, NULL);
How to solve this? 如何解决呢?
It seems like you have Java background, C++ is a bit different. 似乎您具有Java背景,但C ++有点不同。
items = std::vector<std::pair<key_t, value_t>>(d.size_);
items
has already been initialized with its default constructor. items
已使用其默认构造函数进行了初始化。 The line above creates another default initialized container and assigns it to items
, which is unnecessary. 上面的行创建了另一个默认的初始化容器,并将其分配给
items
,这是不必要的。
In: 在:
b.items[0] = item;
You need to make sure that the vector is big enough, because it does not allocate elements for you in operator[]
. 您需要确保向量足够大,因为它不会在
operator[]
为您分配元素。 Either do b.items.push_front/back(item)
or insert it at a specific position using vector::insert
, eg b.items.insert(b.items.begin(), item)
. 请执行
b.items.push_front/back(item)
或使用vector::insert
将其插入特定位置,例如b.items.insert(b.items.begin(), item)
。 push_xxx
and insert
do allocate memory for new elements. push_xxx
和insert
确实为新元素分配内存。
When you do 当你做
for (std::pair<key_t, value_t> item : b.items)
{
if (&item != NULL)
It iterates over all existing elements in the container. 遍历容器中所有现有的元素。
item
is stored by value (unlike Java) in the container, so that it exists at a non-NULL address and cannot be possibly be equal to NULL
. item
通过值(不同于Java)存储在容器中,因此它存在于非NULL地址,并且不可能等于NULL
。
However, expression for(std::pair<key_t, value_t> item : b.items)
creates a copy of each element on the stack (also at non-NULL address), you probably want that to be for(std::pair<key_t, value_t>& item : b.items)
to just refer to the element rather than copy it (note the ampersand symbol on the left of items
). 但是,表达式
for(std::pair<key_t, value_t> item : b.items)
创建堆栈上每个元素的副本(也位于非NULL地址),您可能希望将其作为for(std::pair<key_t, value_t>& item : b.items)
仅引用该元素,而不是复制它(请注意items
左侧的&符号)。 If you do not intend to modify item
inside the loop, you may like to use const
qualifier as well to make your intent clear to the reader of the code. 如果您不打算在循环中修改
item
,则可能还希望使用const
限定符,以使您的意图对代码阅读者更清楚。 eg for(std::pair<key_t, value_t> const& item : b.items)
. 例如
for(std::pair<key_t, value_t> const& item : b.items)
。
And because you use C++11
anyway, you do not have to spell out the type of the container element, just use auto
: 而且因为无论如何都使用
C++11
,所以不必拼写容器元素的类型,只需使用auto
:
for (auto const& item : b.items)
// do something to item
When you create an std::vector
with a length len
like this std::vector<T> tVec(len)
, you are creating a vector
with len
default-constructed objects of type T
. 当创建
std::vector
具有长度len
这样std::vector<T> tVec(len)
要创建一个vector
与len
类型的默认构造的对象T
。 If you want to represent a null value, you will need to resort to one of the following ways: 如果要表示一个空值,则需要采用以下方法之一:
T
to denote an invalid value. T
表示无效值。 T
and use a nullptr
as the natural invalid value. T
指针 ,并使用nullptr
作为自然无效值。 T
which contains a bool
marking it as invalid. T
周围包装一个包含将其标记为无效的bool
的类。 The last option is provided by boost::optional
. 最后一个选项由
boost::optional
。 Here's a rewrite of your code using it: 这是使用它的代码重写:
struct block {
using OptionalPair_t = boost::optional<std::pair<key_t, value_t>>;
std::vector<OptionalPair_t> items;
block(const Data& d) : items(d.size_)
{
}
};
Since boost::optional
is contextually convertible to bool
, you can do this: 由于
boost::optional
在上下文中可以转换为bool
,因此您可以执行以下操作:
for (auto& item : b.items)
{
if (item)
{
...
}
}
I think your mixing here a few definitions. 我认为您在这里混入了一些定义。 an element of
std::vector
cannot be NULL
, because it's not a pointer. std::vector
的元素不能为NULL
,因为它不是指针。 and it defenilty exists. 它存在防御。
int arr[] = {1};
, can arr[0]
be null? ,
arr[0]
可以为null? of course not. 当然不是。 why would it be ?
为什么会这样呢? it's a real integer who seat somwhere in the memory which is not null.
这是一个真正的整数,可以在内存中的任意位置(不为null)。
if you're iterating over a std::vector elements, that means they exist, so they can not be null. 如果要遍历std :: vector元素,则意味着它们存在,因此它们不能为null。
NULL
, or better nullptr
, can be used to initialize a pointer value, but makes no sense to initialize, for example, an std::string
or std::pair<std::string, int>
with it. 可以使用
NULL
或更好的nullptr
初始化指针值,但是用它初始化std::string
或std::pair<std::string, int>
毫无意义。
If you want your vector to be empty, you can use: 如果希望向量为空,则可以使用:
std::vector<std::pair<key_t, value_t>> items;
othwerwise, if you want n
default constructed std::pair
s you can use: 另外,如果您想要
n
默认构造的std::pair
,则可以使用:
std::vector<std::pair<key_t, value_t>> items(n);
Pair are really a comination of values. 配对确实是价值观的融合。 So you have to define which combination of values you consider as being the NULL equivalent for your pairs.
因此,您必须定义将哪些值组合视为对的NULL等效项。
You can then initialize your vector with the following constructor: 然后可以使用以下构造函数初始化向量:
std::vector<std::pair<key_t, value_t>> items(d.size_, make_pair(0,0)) ;
You just have to replace 0 with the neutral values for key_t and value_t. 您只需用key_t和value_t的中性值替换0。
Please note that vectors really contain values, and pairs are values. 请注意,向量实际上包含值,而对是值。 So there is no NULL pointers that would show absence of values.
因此,没有NULL指针会显示缺少值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.