是否有用于固定长度序列的标准容器,其中该长度是在运行时确定的。最好,我想将一个参数传递给每个序列元素的构造函数,并使用该参数来初始化一个 const 成员(或引用)。我还想在 O(1) 中的给定索引处获取序列元素。在我看来,我的所有要求都无法同时满足。
- 我知道
std::array
有固定的长度,但这个长度必须在编译时知道。 std::vector
具有动态大小,并允许使用emplace
. 尽管您可以reserve
记忆以避免实际的重新分配,但该类型仍然必须是可移动的以理论上允许此类重新分配,例如防止 const 成员。- 然后是
std::list
andstd::forward_list
,它不需要可移动类型,但仍然可以调整大小,并且在随机访问模式下表现不佳。我也觉得这样的列表可能会有相当大的开销,因为每个列表节点可能会被单独分配。 - 奇怪的是,
std::valarray
这是我迄今为止最好的选择,因为它有固定的长度并且不会自动调整大小。尽管有一个resize
方法,但除非您实际调用该方法,否则您的类型不必是可移动的。这里的主要缺陷是缺少自定义构造函数参数,因此无法使用这种方法初始化 const 成员。
有没有我错过的替代方案?有没有办法调整一个标准容器以满足我的所有要求?
编辑:为了让您更准确地了解我正在尝试做的事情,请参阅此示例:
class A {
void foo(unsigned n);
};
class B {
private:
A* const a;
const unsigned i;
public:
B(A* aa) : a(aa), i(0) { }
B(A* aa, unsigned ii) : a(aa), i(ii) { }
B(const std::pair<A*, unsigned>& args) : B(args.first, args.second) { }
B(const B&) = delete;
B(B&&) = delete;
B& operator=(const B&) = delete;
B& operator=(B&&) = delete;
};
void A::foo(unsigned n) {
// Solution using forward_list should be guaranteed to work
std::forward_list<B> bs_list;
for (unsigned i = n; i != 0; --i)
bs_list.emplace_front(std::make_pair(this, i - 1));
// Solution by Arne Mertz with single ctor argumen
const std::vector<A*> ctor_args1(n, this);
const std::vector<B> bs_vector(ctor_args1.begin(), ctor_args1.end());
// Solution by Arne Mertz using intermediate creator objects
std::vector<std::pair<A*, unsigned>> ctor_args2;
ctor_args2.reserve(n);
for (unsigned i = 0; i != n; ++i)
ctor_args2.push_back(std::make_pair(this, i));
const std::vector<B> bs_vector2(ctor_args2.begin(), ctor_args2.end());
}