我希望某种std::vector
不能超过const int MAX_LENGTH
元素。我理解我无法覆盖std::vector
非虚函数,我需要做的是对所有相关成员函数进行大小检查(例如assign
,push_back
。 。有这么多)。最明显的方法是将std::vector
包装在class
中,以确保没有操作超出最大长度。但这似乎很笨拙。 是否有比包装类更优雅的解决方案来限制std :: vector大小?
答案 0 :(得分:14)
你确定矢量本身不能增长,或者只是这种矢量的消费者需要限制参数的大小吗?如果是后者,那么只需要assert(arg.size() <= MAX_LENGTH)
,在需要的地方,记录下来,然后完成。否则,请继续阅读。
std::vector
可以有无限大小。如果限制该大小,则不再是std::vector
。因此,您无法公开派生std::vector
并限制大小而不会违反Liskov Substitution Principle。派生类仍然是一个向量,但不能作为一个向量,并且不能用作一个,这样的接口将彻底混淆您的用户,并且编译器将不会捕获随之而来的严重使用错误。这是一个坏主意。
你可以做的最好的事情是私有地从vector派生,或者有一个vector作为成员,并在强制执行大小时公开所有vector的接口。这样的向量必须不可以转换为std::vector
,但显然您可以允许将其复制或移动到std::vector
。它仍然会像矢量那样执行,仍然允许通过迭代器等进行访问。
我们谈论的是一个非常小的课程,其实施只需遵循标准(或至少the cpp reference),您将所有实际工作留给私人std::vector
。所以这不是笨重,这是唯一理智的方式。
答案 1 :(得分:2)
从C ++ 11开始,自定义分配器被允许具有状态(在C ++ 11之前,自定义分配器必须是无状态的)。每个带有自定义分配器的C ++容器都存储它的实例。
然后您的分配器可以检测它是否已经满足了最大分配请求,否则抛出。
答案 2 :(得分:2)
#include <vector>
#include <string>
using namespace std;
template <typename T, typename A>
void add_or_throw(std::vector<T,A> &vec, int max, T value)
{
if (vec.size() < max)
{
vec.push_back(value);
}else{
throw length_error("vecor too beaucoup");
}
}
int main() {
std::vector<std::string> v;
add_or_throw(v, 2, string("hi"));
add_or_throw(v, 2, string("there"));
add_or_throw(v, 2, string("man!"));
return 0;
}