简体   繁体   English

如何使用默认值初始化固定长度的std:pair的std :: vector?

[英]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_xxxinsert确实为新元素分配内存。

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)要创建一个vectorlen类型的默认构造的对象T If you want to represent a null value, you will need to resort to one of the following ways: 如果要表示一个空值,则需要采用以下方法之一:

  1. Use a sentinel value of T to denote an invalid value. 使用前哨值T表示无效值。
  2. Use a (smart-)pointer to T and use a nullptr as the natural invalid value. 使用(智能)指向 T 指针 ,并使用nullptr作为自然无效值。
  3. Wrap a class around 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::stringstd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM