簡體   English   中英

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

[英]How to initialize std::vector of std:pair of fixed length with default values?

假設一個包含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_);
    }
};

在代碼的后面,我為位置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;

在代碼的稍后部分,我想遍歷向量,並期望&bucket_item != NULL僅在位置0處為true,因為我僅在此位置分配了一個值。 實際上, &bucket_item != NULL始終為true。

for (std::pair<key_t, value_t> item : b.items)
{
    if (&item != NULL)
    {
       ...
    }
}

我無法使用NULL值來初始化矢量,如下所示:

items = std::vector<std::pair<key_t, value_t>>(d.size_, NULL);

如何解決呢?

似乎您具有Java背景,但C ++有點不同。

items = std::vector<std::pair<key_t, value_t>>(d.size_);

items已使用其默認構造函數進行了初始化。 上面的行創建了另一個默認的初始化容器,並將其分配給items ,這是不必要的。

在:

b.items[0] = item;

您需要確保向量足夠大,因為它不會在operator[]為您分配元素。 請執行b.items.push_front/back(item)或使用vector::insert將其插入特定位置,例如b.items.insert(b.items.begin(), item) push_xxxinsert確實為新元素分配內存。

當你做

for (std::pair<key_t, value_t> item : b.items) 
{
    if (&item != NULL)

遍歷容器中所有現有的元素。 item通過值(不同於Java)存儲在容器中,因此它存在於非NULL地址,並且不可能等於NULL

但是,表達式for(std::pair<key_t, value_t> item : b.items)創建堆棧上每個元素的副本(也位於非NULL地址),您可能希望將其作為for(std::pair<key_t, value_t>& item : b.items)僅引用該元素,而不是復制它(請注意items左側的&符號)。 如果您不打算在循環中修改item ,則可能還希望使用const限定符,以使您的意圖對代碼閱讀者更清楚。 例如for(std::pair<key_t, value_t> const& item : b.items)

而且因為無論如何都使用C++11 ,所以不必拼寫容器元素的類型,只需使用auto

for (auto const& item : b.items) 
    // do something to item

當創建std::vector具有長度len這樣std::vector<T> tVec(len)要創建一個vectorlen類型的默認構造的對象T 如果要表示一個空值,則需要采用以下方法之一:

  1. 使用前哨值T表示無效值。
  2. 使用(智能)指向 T 指針 ,並使用nullptr作為自然無效值。
  3. T周圍包裝一個包含將其標記為無效的bool的類。

最后一個選項由boost::optional 這是使用它的代碼重寫:

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_)
    {
    }
};

由於boost::optional上下文中可以轉換bool ,因此您可以執行以下操作:

for (auto& item : b.items)
{
    if (item)
    {
       ...
    }
}

我認為您在這里混入了一些定義。 std::vector的元素不能為NULL ,因為它不是指針。 它存在防御。 int arr[] = {1}; arr[0]可以為null? 當然不是。 為什么會這樣呢? 這是一個真正的整數,可以在內存中的任意位置(不為null)。

如果要遍歷std :: vector元素,則意味着它們存在,因此它們不能為null。

可以使用NULL或更好的nullptr初始化指針值,但是用它初始化std::stringstd::pair<std::string, int>毫無意義。

如果希望向量為空,則可以使用:

std::vector<std::pair<key_t, value_t>> items;

另外,如果您想要n默認構造的std::pair ,則可以使用:

std::vector<std::pair<key_t, value_t>> items(n);

配對確實是價值觀的融合。 因此,您必須定義將哪些值組合視為對的NULL等效項。

然后可以使用以下構造函數初始化向量:

std::vector<std::pair<key_t, value_t>> items(d.size_, make_pair(0,0)) ;

您只需用key_t和value_t的中性值替換0。

請注意,向量實際上包含值,而對是值。 因此,沒有NULL指針會顯示缺少值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM