有没有办法使用容器 :: size_type普遍适用于不同类型的T?

问题描述 投票:4回答:2

假设我有一个std::vector<bool> astd::vector<int> b字段的类,我想在构造函数中将reserve()设置为某个大小,这对于两个容器都是相同的。鉴于reserve()接受size_type参数,为了完全安全,我必须 - 从我的理解 - 使用两个参数编写我的构造函数,这不是特别吸引人:

MyCtor(std::vector<bool>::size_type size1, std::vector<int>::size_type size2)
{
    abortIfNotEqual(size1, size2); // Proceed only if size1 == size2
    a.reserve(size1);
    b.reserve(size2);
}

根据我的阅读,size_type通常与size_t相同,至少对于标准容器而言,所以我可能在没有遇到任何潜在问题的情况下这样做:

MyCtor(std::size_t size)
{
    a.reserve(size); // More readable, but is this always ok?
    b.reserve(size);
}

但是,是否有一种更好,更安全的方法来严格使用size_type而无需通过特定的container<T>访问特定类型的T

必须使用特定的container<T>也很烦人,例如访问一个元素:对于a[i]i必须是std::vector<bool>::size_type,因为我假设使用例如unsigned int i不太安全。

在这种情况下,是否存在通用的,通用的,更易读的方式?或者我应该只使用size_t甚至unsigned long int而忘记这一点?

c++ std
2个回答
3
投票

由于您的问题的主要组成部分是如何确保您的安全,而只是假设大小类型相同,我建议使用static_assert std :: is_same。这用c ++ 17编译:

简化符号很重要,所以在这里,我在这个类上键入一个size_type,并在内部确保它与它所代表的两种大小类型相同。如果它们不匹配,则是编译时错误。

#include <vector>

class MyCtor {
    std::vector<bool> a;
    std::vector<int> b;
    typedef std::vector<bool>::size_type st1;
    typedef std::vector<int>::size_type st2;
    static_assert(std::is_same<st1, st2>::value);
public:
    typedef st2 size_type;
    MyCtor(size_type s1, size_type s2) {}
};

特别感谢这个堆栈溢出答案:How to check if two types are same at compiletime(bonus points if it works with Boost strong typedef),其中还包括c ++ 11解决方法。


1
投票

我有这个函数接受两种类型中较小的一种。在C ++ 11中,这可以通过以下方式完成:

#include <vector>
#include <type_traits>
#include <limits>

typedef std::vector<bool>::size_type boolType;
typedef std::vector<int>::size_type intType;

typedef std::conditional<(std::numeric_limits<boolType>::max() <
                          std::numeric_limits<intType>::max()),
                         boolType,
                         intType>::type smallerSizeType;

MyCtor(smallerSizeType size)
{...}

缺少C ++ 11,您可以手动定义自己的std::conditional版本,并用std::numeric_limits<boolType>::max()等替换static_cast<boolType>(-1)

© www.soinside.com 2019 - 2024. All rights reserved.