[英]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.