返回向量大小的getter应该返回什么类型的值?

5

返回向量大小的getter应该返回什么类型的值?

例如,我的项目中有许多以下类型的getter,我需要使用(int)强制转换来消除编译警告:

int getNumberOfBuildings() const { return (int)buildings.size(); }
5个回答

25

C++03的方式:

std::vector<Building>::size_type getNumberOfBuildings() const
{ return buildings.size(); }

C++11的方式:

auto getNumberOfBuildings() const -> decltype(buildings.size())
{ return buildings.size(); }

C++14 的写法:

auto getNumberOfBuildings() const
{ return buildings.size(); }

我宁愿使用我的 int 转换,也不想使用这些东西 :). 除了最后一个,它们都很丑陋,但我们还没有到 C++14... - user2381422
3
@user2381422,但是“int”类型无论在哪里都会引起问题。在比较时,你会收到警告,可能会发生截断,并且如果想要正确的类型,则必须在调用站点进行无意义的工作。 - chris
2
@user2381422:大多数情况下,返回std::size_t是安全的,但是理论上这并不是可移植的,因为标准没有规定对于任何Tstd::size_t应该与std::vector<T>::size_type相同。另外,在使用GCC 4.8.1和Clang 3.3编译时,如果使用-std=c++1y标志,则可以使用最后一种形式。 - Andy Prowl
1
@user2381422,出于某种原因,我更喜欢使用size_type而不是decltype,但它们都提供相同的结果,所以并没有太大关系。 - chris
1
@AndyProwl:实际上,我认为标准确实说std::allocator<T>::size_typesize_t,并且它遵循std::vector<T>::size_type也是size_t。标准没有说std::vector<T,Alloc>::size_type对于任何Alloc都是size_t,所以你是正确的,可能会有其他大小类型的向量。 - Steve Jessop
显示剩余3条评论

5

您应该返回一个std::size_t类型。当您使用默认分配器时,std::size_tvector<T>::size()的返回类型。 vector<T>::size()返回vector<T>::size_type,这只是std::size_t的一个typedef,当您使用默认分配器时(这很可能是您正在使用的)。


4
从技术上讲,返回类型是vector::size_type,它是分配器的size_type的别名,而size_type本身是size_t的别名。如果您有自定义的分配器,它可能会有所不同。 - Oliver Charlesworth
你们所说的默认分配器和自定义分配器有什么区别? - user2381422
1
分配器是一个对象,它管理向量如何获取内存以存储您放入其中的内容。您可以制作自己的自定义分配器,但在大多数情况下,默认的分配器(std::allocator)已经足够好了。 - JKor
+1 是最简单的类型之一,它永远不会出错地正确表示答案。无论你有多少任何类型的对象,你都可以使用 size_t 对它们进行计数,因为你也必须存储它们。 - cmaster - reinstate monica

3

std::vector提供了一个typedef,std::vector<>::size_type,它指示作为vector::size结果使用的类型:

std::vector<TYPE>::size_type getNumberOfBuildings() const { return buildings.size(); }

然而,通常这个类型是size_t,因此您可以直接使用后者:

#include <cstddef>

std::size_t getNumberOfBuildings() const { return buildings.size(); }

那么在我的代码中,我也应该使用 size_t,对吗?例如:size_t temp = myObject.getNumberOfBuildings(); - user2381422
1
@user2381422 是的。如果你使用的是C++11,你可以使用auto关键字:auto temp = myObject.getNumberOfBuildings(); - mfontanini

3
正式的答案确实是std::vector<Building>::size_type,正如其他答案所述。
真正的答案取决于您程序中是否已经有一种类型用来表示建筑物的数量。它可以是int,也可以是unsigned,或者它可能是一些typedef名称TBuildingCount。在这种情况下,您应该使用此类型。它可能需要一个转换以消除编译器警告,但通常都是这样。
我没有看到您代码的其余部分,所以我不能确定,但我猜存储建筑物的某个向量(或任何其他容器)只是一个实现细节,不应影响您计算这些建筑物时选择的类型。甚至不需要以使用其size_type的间接方式公开该容器的存在(或依赖它)来返回计数。
换句话说,如果您已经决定使用int来计算建筑数量,那么您在问题中的实现是您应该坚持的。

我同意这个观点,但是我不得不对最后一个说法提出异议,即提问者“应该”坚持使用C风格的转换。有一些替代方案可能更可取,例如static_cast(有助于某些类型的代码搜索)或boost::numeric_cast(断言前提条件/类不变量,即当前值必须适合于int)。 - Steve Jessop

1
与其他许多答案不同的是,您函数的返回值实际上更多地取决于您的接口而不是您在底层使用的内容。如果您返回向量的大小并希望每个人都知道它,那么请使用std::vector::size_type。但是,如果您实际上返回一些抽象计数变量,例如建筑物的数量,那么我认为std::vector::size_type不应该出现在您的接口中,因为那只是一种实现细节。
如果你返回的是某个东西的大小(但在底层不一定是一个向量),我会使用老式的std::size_t,但如果你返回的是某个东西的数量,那么一个unsigned int在概念上更加合适。当然,没有人保证unsigned intstd::size_t可以容纳任意std::vector的大小,但再次强调,这不是任意的std::vector,它是一组建筑物,您自己应该知道是否会有超过std::numeric_limits<unsigned int>::max()的建筑物。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接