假设我有一个std::vector<bool> a
和std::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
而忘记这一点?
由于您的问题的主要组成部分是如何确保您的安全,而只是假设大小类型相同,我建议使用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解决方法。
我有这个函数接受两种类型中较小的一种。在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)
。