簡體   English   中英

std::vector emplace_back 實現

[英]std::vector emplace_back implementation

我實現的 push_back function:

void push_back(T& num) {
    my_vec[index] = num;
    index++;
}

還有 emplace_back function:

template<class... Args>
void emplace_back(Args&&... args) {
    push_back(T(std::forward<Args>(args)...));
}

你覺得這有什么問題嗎? 如果是,那么你能告訴我嗎

另外,請讓我知道這是如何工作的?

請注意:emplace_back 不是我的實現,我從其他問題中獲取它,因為我正在尋找一種方法來實現我自己的 emplace_back。

你覺得這有什么問題嗎?

你並沒有真正接受這個。 還有一個任務。

std::vector<T>分配T數組。 它使用T數組的大小和 alignment 分配原始 memory ,然后在該原始 memory 中實例化對象。

考慮到這一點,您可能應該根據emplace_back實現push_back ,而不是相反。

template <typename T>
class my_vector {
    T * start;
    std::size_t size;
    std::size_t capacity;

    void grow(); // Implementation of this is left as an exercise to the reader

public:
    template <typename... Args>
    reference emplace_back(Args&&... args) {
        if (size == capacity) grow();
        return *new (start + size++) T(std::forward<Args>(args)...);
    }

    reference push_back(const T & t) { return emplace_back(t); }
    reference push_back(T && t) { return emplace_back(std::move(t)); }
}

另外,請讓我知道這是如何工作的?

template <typename... Args>允許零個或多個類型與此模板匹配,然后T(std::forward<Args>(args)...)正在用那些 arguments 構造一個T“完美轉發”它們,即右值作為右值傳遞,左值作為左值傳遞。

注意,因為std::vector不是new[] ,所以您不能在 C++ 20 之前實現與std::vector完全相同的東西,因為它必須能夠在不構造數組的情況下從data中返回指向T數組的指針的T

emplace_back的重點是在原地構造一個 object。 您的實現構造一個 object 然后將其復制到my_vec

您的實現不適用於不可復制的類型。 例如,這不會編譯:

Vector<std::thread> v;
v.emplace_back([](){});
v.push_back(std::thread([](){}));

更改push_back以通過右值引用獲取它的參數將解決問題:

void push_back(T&& num) {
    my_vec[index] = std::move(num);
    index++;
}

template<class... Args>
void emplace_back(Args&&... args) {
    push_back(T(std::forward<Args>(args)...));
}

然而,我認為大多數標准庫實現都是使用emplace_back作為最低級別的 function 實現的:

void push_back(T&& num) {
    emplace_back(std::move(num));
}

template<class... Args>
void emplace_back(Args&&... args) {
    my_vec[index] = T(std::forward<Args>(args)...);
    index++;
}

這樣就更容易實現復制值的push_back重載:

void push_back(const T& num) {
    emplace_back(num);
}

請注意,此實現正在使用移動分配,這仍然不是emplace_back的意圖,它需要在未初始化的 memory 上使用放置新的位置構造一個 object 但假設my_vec是一個對象數組或類似的最好的你可以做的(沒有完全實現std::vector的語義相當復雜)。

暫無
暫無

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

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