簡體   English   中英

使用 std::vector 時如何將索引信息傳遞給元素構造函數?

[英]How to pass index information to element constructor when using std::vector?

有什么方法可以將向量的索引傳遞給它的元素的構造函數? 例如:

#include <iostream>
#include <vector>

class Foo {
 public:
  Foo(unsigned long index) {
    std::cout << index << std::endl;
  }
};

int main() {
  std::vector<Foo> foo;
  foo.resize(2); // any way to make this work?
}

這段代碼確實不起作用,因為編譯器不知道如何構造Foo(unsigned long index) ,但是我可以做一些技巧(例如自定義分配器?)來使這段代碼真正起作用?

您可以在 for 循環中添加元素並將索引作為參數傳遞給它們的 ctor,如下所示:

// Init your vector + optionally reserve space
std::vector<Foo> foo;
const unsigned elements_to_add = 5; // or whatever number
foo.reserve(foo.size() + elements_to_add);

// foo.size() will be passed as parameter to the ctor you defined
for (std::size_t i = 0; i < elements_to_add; i++) {
    foo.emplace_back(foo.size());
}

不,您將要使用std::generate()std::generate_n()std::back_inserter()結合使用。

我想有很多方法可以或多或少地得到你想要的。 但遲早,你可能會發現你不需要這個。

這是一個可能的解決方案:

#include <iostream>
#include <vector>

class Foo
{
    inline static unsigned long _static_index = 0;
    unsigned long _index;

public:
    Foo() : _index(_static_index) { ++_static_index; }

    auto index() const { return _index; }
    static void resetIndex() { _static_index = 0; }
};

int main()
{
    std::vector<Foo> foos;
    Foo::resetIndex();
    foos.resize(2);

    for (const auto& f : foos)
        std::cout << f.index() << std::endl;

    return 0;
}

因此,您只需增加一個 static 計數器並將其分配給私有成員_index 這顯然有其局限性。 例如,假設您在填充Foo vector之前創建了 3 個Foo實例,那么foos[0].index()將返回 3 而不是 0。因此,在填充foos之前,您需要重置_static_index

您可以編寫一個自定義的全狀態分配器,該分配器將在構造 object 時傳遞一個索引。

最小的例子:

template<class T>
class Allocator {
public:
    using value_type = T;

    T* allocate(std::size_t n) {
        return static_cast<T*>(::operator new(n * sizeof(T)));
    }

    void deallocate(T* p, std::size_t) noexcept {
        ::operator delete(p);
    }

    template<class... Args>
    void construct(T* p, Args&&... args) {
        ::new(static_cast<void*>(p)) T(counter_++, std::forward<Args>(args)...);
    }

    void destroy(T* p) noexcept {
        p->~U();
        --counter_;
    }

private:
    std::size_t counter_ = 0;
};

使用示例:

struct Foo {
    Foo(std::size_t index) {
        std::cout << index << ' ';
    }

    Foo(std::size_t index, const Foo& other) : Foo(other) {
        std::cout << index << ' ';
    }
};

std::vector<Foo, Allocator<Foo>> foos1;
foos1.resize(3);
std::cout << std::endl;

std::vector<Foo, Allocator<Foo>> foos2;
foos2.resize(4);

// Output: 
// 0 1 2 
// 0 1 2 3

暫無
暫無

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

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