在std :: vector上强制执行大小约束的非侵入式方法?

时间:2015-07-31 16:06:12

标签: c++

我希望某种std::vector不能超过const int MAX_LENGTH元素。我理解我无法覆盖std::vector非虚函数,我需要做的是对所有相关成员函数进行大小检查(例如assignpush_back。 。有这么多)。最明显的方法是将std::vector包装在class中,以确保没有操作超出最大长度。但这似乎很笨拙。 是否有比包装类更优雅的解决方案来限制std :: vector大小?

3 个答案:

答案 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;
}