我经常有一些类,它们大多只是一些STL容器的包装器,如下所示:
class Foo {
public:
typedef std::vector<whatever> Vec;
typedef Vec::size_type size_type;
const Vec& GetVec() { return vec_; }
size_type size() { return vec_.size() }
private:
Vec vec_;
};
我不太确定要回归size_type
。通常,某些函数会调用size()
并将该值传递给另一个函数,并且该函数将使用它并可能将其传递给它。现在每个人都必须包含那个Foo标题,虽然我真的只是传递一些大小的值,但这应该只是unsigned int
......?这里做什么是正确的?在各地真正使用size_type
是最佳做法吗?
答案 0 :(得分:7)
STL将这些类型定义为容器的抽象接口。它旨在支持任何类型的后备存储。这可能是NUMA或磁盘支持的存储,其中size_type
和ptr-type
与系统内存不同。或者 - 在NUMA架构中 - 它可能是一个快速的特定内存节点,并且可以使用非常小的size_type
和ptr_type
- 这是许多架构上的相关优化。
至少,这是设计目标,也是由于预期可以成为支持C ++的平台。一些早期的让步也允许STL实现者的快捷方式基本上禁用了这种灵活性,而且我从未使用过使用它的STL实现。我之所以这样说是因为线性内存访问已经变得不那么成问题了,而且那个级别的STL开发实际上并不容易。
但是,它对你有多大伤害?这是正确的做法。
答案 1 :(得分:6)
应该像你一样vector<>::size_type
,这是最正确的方法。
那就是说,我知道包括我在内的很多人只会使用size_t
。虽然它不是必须相同的,但对于我所知道的每个实现,vector<>::size_type
都是size_t
。你应该没问题。
答案 2 :(得分:5)
实际上,对于64位兼容性,它应该是size_t而不是unsigned int。作为包装类编写器,我将返回size_type。作为类客户端,如果更方便的话,我会将其转换为适当的类型(size_t)。
答案 3 :(得分:1)
我不太确定要回来 尺码类型。通常,某些功能会 调用size()并将该值传递给 另一个功能,一个将使用 它可能会传递给它。现在大家 必须包括那个Foo标题...
可以返回size_type
,但这并不意味着另一个函数必须与类中的typedeffed采用相同的size_type
。整数类型之间存在转换。要勇敢,只需使用size_t
。
无论如何都不能重载函数,以便有一个适用于size
向量的函数,另一个函数用于deque
等大小,以防它们碰巧使用不同的{ {1}}(标准可能允许)。 - 但是如果可能的话,您也可以使用模板来推断出要在参数中使用的正确size_type
。
答案 4 :(得分:-1)
您可以考虑的一个选项是继承std::vector
:
typedef std::vector<whatever> Foo_Vec;
class Foo : public Foo_Vec
{
public:
const Foo_Vec &GetVec() { return (Foo_Vec&)*this; }
};
我绝不是说这是最好的方法,因为它可以引入私有成员或从private Foo_Vec
继承而不会发生的问题,因为public Foo_Vec
公开了std::vector
上的所有方法{1}}到Foo
。此外,std::vector
没有虚拟析构函数,因此如果您尝试清除隐藏在其中的Foo的std::vector
集合,则不会完全清除它。我只是把它扔出去了。
正如其他答案所示,您应该使用size_t
或size_type
而不是unsigned int
来实现64位兼容性。否则,在将来的64位版本中,您的std::vector
可能会有超过2个 32 项,但是大小值会被截断,从而导致错误。