C++ 我需要向量的最大大小(我给出的值)C++;

C++ 我需要向量的最大大小(我给出的值)C++;,c++,vector,C++,Vector,我有以下代码: 固定大小的向量: template <typename T, size_t siz> struct fixVec : public std::vector<T> { void push_back(const T& d) { if (std::vector<T>::size() >= siz) throw std::bad_alloc(); std::vector<T>::push_back(d)

我有以下代码:

固定大小的向量:

template <typename T, size_t siz>
struct fixVec : public std::vector<T> {
    void push_back(const T& d) {
    if (std::vector<T>::size() >= siz) throw std::bad_alloc();
    std::vector<T>::push_back(d);
}
};
它添加了1个元素,很好,没有错误(2)

在这里,它应该抛出异常(3)

我的问题是:当我达到向量的“max_size()”时,如何检查。不是我的电脑能处理的向量的最大大小。 或者,我如何才能取回我在代码(1)(两者之间的数字!)中给出的值:

ClonableheterostoreT1;
我有一个名为ClonableHeteroStore的类,其中有以下代码:

template <typename T1, class S, typename PRED = int>
class ClonableHeteroStore 
{
private:
    S flakker;
    size_t currently;
    size_t maxi;
public:
    ClonableHeteroStore() :  { currently = 0; maxi = 0; }

    void add(T1 *rhs)
    {
        if (currently < ???????? )
        {
            flakker.push_back(rhs);
            currently++;
        }
        else
        {
            delete rhs;
            throw PRED();
        }
    }
...
模板
ClonableHeteroStore类
{
私人:
S弗莱克;
目前的规模;
最大尺寸;
公众:
ClonableHeteroStore():{current=0;maxi=0;}
无效添加(T1*rhs)
{
如果(当前<???????)
{
flakker.向后推(右舵);
目前为++;
}
其他的
{
删除rhs;
抛出PRED();
}
}
它应该做什么: 如果未达到代码(1)中给出的向量的最大大小,则应向向量添加新元素。如果达到代码(1)中给出的限制,则应删除异常

所以第(2)行不会有任何问题,因为向量的大小是1,这是我们放入其中的第一个元素。“if”部分应该运行

(3)将引发异常,因为它尝试放置第二个元素,但向量大小为1。应运行“else”部分

唯一可以更改的代码是ClonableHeteroStore类。不知何故,我应该知道我的向量有多大。我读了很多关于向量是如何动态分配大小等的内容,但在这种情况下,如果我跳过限制(1),它必须抛出异常


感谢您的帮助!

从类型中提取模板参数的两种常见解决方案是使用部分显式专门化或使用函数模板从函数参数推断模板参数的类型特征。基于函数的方法包括编写一个需要
fixVec
和getti的函数ng编译器以推断
I

// The compiler will deduce T and I from the argument
template<class T, size_t I>
size_t get_vec_size(const fixVec<T, I> &) {
    return I;
}

void foo()
{
    fixVec<char, 10> my_vec;
    const auto my_vec_max_size = get_vec_size(my_vec);
}
//编译器将从参数推导出T和I
模板
大小获取向量大小(常量固定向量&){
返回I;
}
void foo()
{
fixVec my_vec;
const auto my_vec_max_size=get_vec_size(my_vec);
}
要使用部分显式专门化,您需要编写一个新模板,并将其专门化为所需模板参数的类型,然后再次让编译器为您推导这些参数:

template<class T>
struct vec_size {};

template<class T, size_t I>
struct vec_size<fixVec<T, I>> : std::integral_constant<size_t, I> {};

void foo()
{
    fixVec<char, 10> my_vec;
    const auto my_vec_max_size = vec_size<decltype(my_vec)>::value;
}
模板
结构向量大小{};
模板
结构向量大小:std::integral_常量{};
void foo()
{
fixVec my_vec;
const auto my_vec_max_size=vec_size::value;
}

从类型中提取模板参数的两种常见解决方案是使用部分显式专门化的类型特征,或者使用函数模板从函数参数中推断模板参数。基于函数的方法包括编写一个需要
fixVec
的函数,并将编译器编译为d导出
I

// The compiler will deduce T and I from the argument
template<class T, size_t I>
size_t get_vec_size(const fixVec<T, I> &) {
    return I;
}

void foo()
{
    fixVec<char, 10> my_vec;
    const auto my_vec_max_size = get_vec_size(my_vec);
}
//编译器将从参数推导出T和I
模板
大小获取向量大小(常量固定向量&){
返回I;
}
void foo()
{
fixVec my_vec;
const auto my_vec_max_size=get_vec_size(my_vec);
}
要使用部分显式专门化,您需要编写一个新模板,并将其专门化为所需模板参数的类型,然后再次让编译器为您推导这些参数:

template<class T>
struct vec_size {};

template<class T, size_t I>
struct vec_size<fixVec<T, I>> : std::integral_constant<size_t, I> {};

void foo()
{
    fixVec<char, 10> my_vec;
    const auto my_vec_max_size = vec_size<decltype(my_vec)>::value;
}
模板
结构向量大小{};
模板
结构向量大小:std::integral_常量{};
void foo()
{
fixVec my_vec;
const auto my_vec_max_size=vec_size::value;
}
有趣的问题

例如,您可以使用:

有趣的问题

例如,您可以使用:

固定大小的向量:

template <typename T, size_t siz>
struct fixVec : public std::vector<T> {
    void push_back(const T& d) {
    if (std::vector<T>::size() >= siz) throw std::bad_alloc();
    std::vector<T>::push_back(d);
}
};
对于“固定”数组,为什么使用
std::vector
而不是
std:array

它创建一个大小为1的向量。(1)

不,它不是。它创建了一个
向量
,其
size()
capacity()
最初是0,而不是1。您的
siz
值被用作一个人工最大容量,您仍然允许向量动态增长,直到达到最大容量

在这里,它应该抛出异常

是的,更糟糕的是,它会泄漏
ClonableTestClass
对象。您应该改为使用
std::unique\u ptr
,以便始终保持对象的所有权并正确释放它,即使引发异常也是如此

当我达到向量的“max_size()”时,如何进行检查

你已经是了。这正是
size()>=siz
正在做的

或者,我怎样才能得到我在代码(1)中给出的值(两个值之间的数字!):

或者,如果您使用的是C++11或更高版本:

template <typename T, size_t siz>
struct fixVec : public std::vector<T>
{
    const size_t max_elements_allowed = siz;
    ...
};
std::unique_ptr<ClonableTestClass> obj(new ClonableTestClass);
t1.add(obj.get());
obj.release();
也就是说,
std::vector
有一个方法,这就是您真正想要的:

void add(T1 *rhs)
{
    if (flakker.size() < flakker.capacity())
    {
        flakker.push_back(rhs);
    }
    else
    {
        delete rhs;
        throw PRED();
    }
}
我有一个名为ClonableHeteroStore的类,其中有以下代码:

template <typename T1, class S, typename PRED = int>
class ClonableHeteroStore 
{
private:
    S flakker;
    size_t currently;
    size_t maxi;
public:
    ClonableHeteroStore() :  { currently = 0; maxi = 0; }

    void add(T1 *rhs)
    {
        if (currently < ???????? )
        {
            flakker.push_back(rhs);
            currently++;
        }
        else
        {
            delete rhs;
            throw PRED();
        }
    }
...
它应该做什么:如果我们没有达到代码(1)中给出的向量的最大大小,它应该向向量添加一个新元素。如果我们达到代码(1)中给出的限制,它应该删除一个异常

由于您的
fixVec
已经在处理该问题,您应该无条件地添加元素,并在需要时让
push_back()
抛出:

void add(T1 *rhs)
{
    try
    {
        flakker.push_back(rhs);
    }
    catch (...)
    {
        delete rhs;
        throw PRED();
    }
}
更好的设计是让调用者保留所添加对象的所有权,除非
add()
成功,否则不要释放该所有权。这样,如果引发异常,调用者可以正确释放该对象,而不会泄漏它。这不应该是
add()
处理的责任:

void add(T1 *rhs)
{
    try
    {
        flakker.push_back(rhs);
    }
    catch (...)
    {
        throw PRED();
    }
}

...

ClonableTestClass *obj = new ClonableTestClass;
try
{
    t1.add(obj);
}
catch (...)
{
    delete obj;
    throw;
}
或者,如果您使用的是C++11或更高版本:

template <typename T, size_t siz>
struct fixVec : public std::vector<T>
{
    const size_t max_elements_allowed = siz;
    ...
};
std::unique_ptr<ClonableTestClass> obj(new ClonableTestClass);
t1.add(obj.get());
obj.release();
但是这个
template <typename T, size_t siz>
struct fixVec : public std::vector<T>
{
    fixVec() { std::vector<T>::reserve(siz); } // <-- add this!
    ...
};
...
void add(T1 *rhs)
{
    try
    {
        flakker.push_back(rhs);
    }
    catch (...)
    {
        delete rhs;
        throw PRED();
    }
}
void add(T1 *rhs)
{
    try
    {
        flakker.push_back(rhs);
    }
    catch (...)
    {
        throw PRED();
    }
}

...

ClonableTestClass *obj = new ClonableTestClass;
try
{
    t1.add(obj);
}
catch (...)
{
    delete obj;
    throw;
}
std::unique_ptr<ClonableTestClass> obj(new ClonableTestClass);
t1.add(obj.get());
obj.release();
void add(std::unique_ptr<T1> rhs)
{
    try
    {
        flakker.push_back(rhs.get());
        rhs.release();
    }
    catch (...)
    {
        throw PRED();
    }
}

...

t1.add(std::unique_ptr<ClonableTestClass>(new ClonableTestClass));
template<typename T, size_t siz>
size_t get_capacity(const fixVec<T, siz> &) { return siz; }

...

void add(T1 *rhs)
{
    if (flakker.size() < get_capacity(flakker))
        flakker.push_back(rhs);
    else
        throw PRED();
}