在 class 构造函数中为元素构造函数设置不同的值 std::vector
Setup std::vector in class constructor with different values for element constructor
我有一个 class 和一个非平凡的构造函数:
class mystream
{
public:
mystream(size_t buffersize,size_t index) : buffersize(buffersize),index(index){}
size_t buffersize;
size_t index;
};
mystream
实例有一个唯一的 id,它对应于它在管理 class:
的向量中的位置
class mystreammanager
{
public:
mystreammanager() : streams(8,1024, /* WHAT TO DO HERE ??? */ )
{
}
std::vector<mystream> streams;
};
如何构建向量并使用索引的升序值初始化其元素?
只需使用一个循环:
mystreammanager() {
streams.reserve(8);
for (int i = 0; i < 8; ++i) {
streams.emplace_back(1024, i);
}
}
你可以这样做:
class mystreammanager
{
public:
mystreammanager() : streams{{1024, 0}, {1024, 1}, {1024, 2}, {1024, 3},
{1024, 4}, {1024, 5}, {1024, 6}, {1024, 7}}
{
}
std::vector<mystream> streams;
};
但是做一个循环似乎safer/simpler。
一种简洁、清晰且易于调试的方法是将向量的构造推迟到 static class 函数:
class mystreammanager
{
public:
mystreammanager() : streams{ generate_streams(1024, 8) }
{
}
private:
static std::vector<mystream> generate_streams(size_t buffersize, size_t qty)
{
std::vector<mystream> result;
result.reserve(qty);
for(size_t i = 0 ; i < qty ; ++qty) {
result.emplace_back(buffersize, i);
}
return result;
}
std::vector<mystream> streams;
};
这是最有效的,因为:
- RVO 导致就地构建向量
- 避免列表初始化意味着没有冗余副本。
编译时版本:)
需要 c++14
,但肯定可以适应 c++11
#include <cstddef>
#include <vector>
#include <utility>
class mystream
{
public:
mystream(size_t buffersize,size_t index) : buffersize(buffersize),index(index){}
size_t buffersize;
size_t index;
};
template<size_t... Indexes>
std::initializer_list<mystream> mystream_maker_impl(std::index_sequence<Indexes...>)
{
return {{1024, Indexes}...};
}
template<size_t N>
std::initializer_list<mystream> mystream_maker()
{
return mystream_maker_impl(std::make_index_sequence<N>());
}
class mystreammanager
{
public:
mystreammanager() : streams(mystream_maker<8>())
{
}
std::vector<mystream> streams;
};
我使用了@RichardHodges 的回答,因为我对我的第一选择不满意。
我想到了这个模板:
template<class T,class ...Args> std::vector<T> generate_with_index(size_t qty,Args ...args)
{
std::vector<T> result;
result.reserve(qty);
for(size_t i = 0 ; i < qty ; ++qty)
result.emplace_back(i, args...);
return result;
}
它帮助我避免冗余。从理论上讲,我最喜欢@Drax 解决方案,因为它在编译期间完成了最多的工作。
我有一个 class 和一个非平凡的构造函数:
class mystream
{
public:
mystream(size_t buffersize,size_t index) : buffersize(buffersize),index(index){}
size_t buffersize;
size_t index;
};
mystream
实例有一个唯一的 id,它对应于它在管理 class:
class mystreammanager
{
public:
mystreammanager() : streams(8,1024, /* WHAT TO DO HERE ??? */ )
{
}
std::vector<mystream> streams;
};
如何构建向量并使用索引的升序值初始化其元素?
只需使用一个循环:
mystreammanager() {
streams.reserve(8);
for (int i = 0; i < 8; ++i) {
streams.emplace_back(1024, i);
}
}
你可以这样做:
class mystreammanager
{
public:
mystreammanager() : streams{{1024, 0}, {1024, 1}, {1024, 2}, {1024, 3},
{1024, 4}, {1024, 5}, {1024, 6}, {1024, 7}}
{
}
std::vector<mystream> streams;
};
但是做一个循环似乎safer/simpler。
一种简洁、清晰且易于调试的方法是将向量的构造推迟到 static class 函数:
class mystreammanager
{
public:
mystreammanager() : streams{ generate_streams(1024, 8) }
{
}
private:
static std::vector<mystream> generate_streams(size_t buffersize, size_t qty)
{
std::vector<mystream> result;
result.reserve(qty);
for(size_t i = 0 ; i < qty ; ++qty) {
result.emplace_back(buffersize, i);
}
return result;
}
std::vector<mystream> streams;
};
这是最有效的,因为:
- RVO 导致就地构建向量
- 避免列表初始化意味着没有冗余副本。
编译时版本:)
需要 c++14
,但肯定可以适应 c++11
#include <cstddef>
#include <vector>
#include <utility>
class mystream
{
public:
mystream(size_t buffersize,size_t index) : buffersize(buffersize),index(index){}
size_t buffersize;
size_t index;
};
template<size_t... Indexes>
std::initializer_list<mystream> mystream_maker_impl(std::index_sequence<Indexes...>)
{
return {{1024, Indexes}...};
}
template<size_t N>
std::initializer_list<mystream> mystream_maker()
{
return mystream_maker_impl(std::make_index_sequence<N>());
}
class mystreammanager
{
public:
mystreammanager() : streams(mystream_maker<8>())
{
}
std::vector<mystream> streams;
};
我使用了@RichardHodges 的回答,因为我对我的第一选择不满意。 我想到了这个模板:
template<class T,class ...Args> std::vector<T> generate_with_index(size_t qty,Args ...args)
{
std::vector<T> result;
result.reserve(qty);
for(size_t i = 0 ; i < qty ; ++qty)
result.emplace_back(i, args...);
return result;
}
它帮助我避免冗余。从理论上讲,我最喜欢@Drax 解决方案,因为它在编译期间完成了最多的工作。