第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在C ++ 11和Boost.Container下vector :: resize

在C ++ 11和Boost.Container下vector :: resize

C++
眼眸繁星 2019-10-11 14:44:58
我有一個C ++ 03應(yīng)用程序,其中std::vector<T>類型始終用作臨時緩沖區(qū)。因此,通常會使用std::vector<T>::resize()來調(diào)整它們的大小,以確保它們足夠大以在使用前容納所需的數(shù)據(jù)。該函數(shù)的C ++ 03原型實際上是:void resize(size_type n, value_type val = value_type());因此實際上在調(diào)用時resize(),通過添加適當(dāng)數(shù)量的拷貝來擴大向量val。但是,通常,我只需要知道它vector足夠容納我所需的數(shù)據(jù)即可。我不需要將其初始化為任何值。復(fù)制構(gòu)造新值只是浪費時間。C ++ 11可以解決(我認(rèn)為):在其規(guī)范中,它分為resize()兩個重載:void resize(size_type n); // value initializationvoid resize(size_type n, const value_type &val); // initialization via copy這很符合C ++的哲學(xué):只為您想要的付出。但是,正如我指出的那樣,我的應(yīng)用程序不能使用C ++ 11,因此當(dāng)我遇到Boost.Container庫時就感到很高興,該庫在其文檔中指出了對該功能的支持。具體來說,boost::container::vector<T>實際上有三個重載resize():void resize(size_type n); // value initializationvoid resize(size_type n, default_init_t); // default initializationvoid resize(size_type n, const value_type &val); // initialization via copy為了驗證我是否了解所有內(nèi)容,我快速進行了一次測試以驗證C ++ 11 std::vector<T>和的行為boost::container::vector<T>:#include <boost/container/vector.hpp>#include <iostream>#include <vector>using namespace std;namespace bc = boost::container;template <typename VecType>void init_vec(VecType &v){    // fill v with values [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]    for (size_t i = 0; i < 10; ++i) v.push_back(i);    // chop off the end of v, which now should be [1, 2, 3, 4, 5], but the other 5 values    // should remain in memory    v.resize(5);}g++在C ++ 03模式下使用4.8.1進行編譯,如下所示:g++ vectest.cc./a.out產(chǎn)生以下輸出:std: 0 1 2 3 4 0 0 0 0 0 boost: 0 1 2 3 4 0 0 0 0 0 boost w/default: 0 1 2 3 4 5 6 7 8 9這并不奇怪。我希望C ++ 03 std::vector<T>用零初始化最后的5個元素。我什至可以說服自己為什么boost::container::vector<T>要這樣做(我會假設(shè)它模仿C ++ 03模式下的C ++ 03行為)。當(dāng)我明確要求默認(rèn)初始化時,才得到想要的效果。但是,當(dāng)我以C ++ 11模式重建時,如下所示:g++ vectest.cc -std=c++11./a.out我得到以下結(jié)果:std: 0 1 2 3 4 0 0 0 0 0 boost: 0 1 2 3 4 0 0 0 0 0 boost w/default: 0 1 2 3 4 5 6 7 8 9一模一樣!這導(dǎo)致了我的問題:在這種情況下,我應(yīng)該從三個測試中看到相同的結(jié)果,這是我的錯嗎?這似乎表明std::vector<T>接口更改并沒有真正起任何作用,因為resize()在前兩種情況下,最后一次調(diào)用中添加的5個元素仍然用零初始化。
查看完整描述

3 回答

?
12345678_0001

TA貢獻(xiàn)1802條經(jīng)驗 獲得超5個贊

因此,實際上,在調(diào)用resize()時,通過添加適當(dāng)數(shù)量的val副本來擴大向量。但是,通常,我只需要知道向量足夠大即可容納我需要的數(shù)據(jù)。我不需要將其初始化為任何值。復(fù)制構(gòu)造新值只是浪費時間。


不,不是。擁有實際上沒有構(gòu)造的元素的容器是沒有意義的。我不確定您希望看到的不是零。未指定/未初始化的元素?這不是價值初始化的意思。


如果您需要N個元素,那么您應(yīng)該有N個正確構(gòu)造的元素,這就是需要的std::vector::resize。值初始化將使對象初始化為零,而沒有默認(rèn)構(gòu)造函數(shù)可調(diào)用,因此,實際上這與您想要的相反,安全性和初始化程度較低,而不是更多。


我建議你真正想要的是std::vector::reserve。


這似乎表明std::vector<T>界面更改并未真正起任何作用


它肯定會產(chǎn)生作用,但不是您要尋找的那個。新的resize重載是為了方便起見,因此當(dāng)您只需要默認(rèn)或什至值初始化時,您就不必構(gòu)造自己的臨時文件。這不是容器工作方式的根本變化,而是它們始終持有有效的?類型的?實例。


?有效,但如果您離開它們,則處于未指定狀態(tài)!


查看完整回答
反對 回復(fù) 2019-10-11
?
飲歌長嘯

TA貢獻(xiàn)1951條經(jīng)驗 獲得超3個贊

還有就是用C ++ 11個小功能上的差異resize簽名,但您的測試不會揭露它??紤]類似的測試:


#include <iostream>

#include <vector>


struct X

{

    X() {std::cout << "X()\n";}

    X(const X&) {std::cout << "X(const X&)\n";}

};


int

main()

{

    std::vector<X> v;

    v.resize(5);

}

在C ++ 03下打?。?/p>


X()

X(const X&)

X(const X&)

X(const X&)

X(const X&)

X(const X&)

但是在C ++ 11下它會打印:


X()

X()

X()

X()

X()

進行此更改的動機是為了更好地支持中的不可復(fù)制(僅移動)類型vector。在大多數(shù)情況下,包括您的情況在內(nèi),此更改都沒有影響。


有一種方法可以通過使用自定義分配器(您的編譯器可能支持或可能不支持)來完成C ++ 11中的目標(biāo):


#include <iostream>

#include <vector>


using namespace std;


template <class T>

class no_init_alloc

    : public std::allocator<T>

{

public:

    using std::allocator<T>::allocator;


    template <class U, class... Args> void construct(U*, Args&&...) {}

};



template <typename VecType>

void init_vec(VecType &v)

{

    // fill v with values [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    v.resize(10);

    for (size_t i = 0; i < 10; ++i) v[i] = i;  // Note this change!!!

    // chop off the end of v, which now should be [1, 2, 3, 4, 5], but the other 5 values

    // should remain in memory

    v.resize(5);

}


template <typename VecType>

void print_vec(const char *label, VecType &v)

{

    cout << label << ": ";

    for (size_t i = 0; i < v.size(); ++i)

    {

        cout << v[i] << ' ';

    }

    cout << endl;

}


int

main()

{

    std::vector<int, no_init_alloc<int>> std_vec;

    init_vec(std_vec);

    std_vec.resize(10);

    print_vec("std", std_vec);

}

哪個應(yīng)該輸出:


std: 0 1 2 3 4 5 6 7 8 9 

在no_init_alloc簡單地拒絕做任何初始化,這是罰款int,有一個未確定的值離開它。我不得不更改您init_vec使用賦值來初始化而不是使用構(gòu)造。因此,如果您不小心,可能會很危險/令人困惑。但是,它的確避免了不必要的初始化。


查看完整回答
反對 回復(fù) 2019-10-11
  • 3 回答
  • 0 關(guān)注
  • 809 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號