我应该在我的代码中使用size_type吗?

3

我是一名有用的助手,可以为您翻译文本。

我有一组不同类型的容器,每个容器都与一个字符串ID相关联。如果关联的容器不为空,则以下函数应打印该ID。

如果我想将std::vector的大小传递给函数,我应该将其作为size_type对象传递吗?像这样:

void printIfNotEmpty(const std::string& id, size_type sizeOfContainer)
{
   if(sizeOfContainer)
   {
     output << id << " is not empty";
   }
   else
   {
     output << id << " is empty";
   }
}

如果是这样,size_type在哪个命名空间中?我如何将其定义包含在我的代码中?也许这是一个解决方案:
template<class T>
void printIfNotEmpty(const std::string& id, const T& container)
{
  if(container.size())
  {
     output << id << " is not empty";
  }
  else
  {
     output << id << " is empty";
  }
}

这是一个成员类型定义:std::vector<T>::size_type - jrok
@billz 不,另一个容器。 - Baz
1
为什么要传递大小?你可以从传递的向量或字符串中获取它。 - juanchopanza
1
你仍然不需要将大小作为单独的参数传递。 - juanchopanza
@juanchopanza 如果我传递一个向量的引用,那就不需要模板化我的类,这样它就可以处理vector<A>和vector<B>等。我认为只需发送大小而不考虑向量类型可能是可能的。 - Baz
显示剩余4条评论
5个回答

6
我应该将其作为size_type对象传递吗?
这是最具可移植性的做法。(顺便说一下,它不是“对象”的意义上的类类型;它是一个无符号整数类型,足以表示任何向量的大小)。
如果您知道它是具有标准分配器的向量,并且未来不太可能更改,则使用std::size_t可能会更简洁。
(当然,在这个简单的例子中,传递布尔标志或删除条件并使调用者负责决定是否调用函数会更有意义;但我假设它旨在表示更复杂的情况,在这些情况下传递大小是有意义的)。
如果是这样,请问size_type在哪个命名空间中?
每个标准容器(以及任何其他设计满足标准容器要求的容器)都将其定义为嵌套类型。
我如何在我的代码中包含它的定义?
定义在中;必须将其限定为std :: vector :: size_type。
std :: size_t定义在中。

2
据我了解,大小并不是指字符串的大小,所以如果你只需要执行代码的话,可以像这样做:
void printIfNotEmpty(const std::string& name, bool empty) {
  if(!empty) {
    output << name;
  }
}

并将其命名为:

printIfNotEmpty(a_string, a_vector.empty());

然而在处理大小时,我通常使用一个通用的size_t类型,它是一个无符号整数类型,其大小取决于平台。在此处隐式类型转换是可行的,因此您无需通过声明如std :: vector<T> :: size_type这样的内容来重载代码,这些通常只是size_t的typedef。


2

size_type 是来自于 std 的类型,它并不是一个对象。值得一提的是,为了保证可移植性,你应该使用它。例如,在 Win64 上,如果你使用一个 int ,你会收到转换警告,因为在该平台上,size_typeint 更大。

在深入探讨之前,请查看'size_t' vs 'container::size_type'


在命名空间std中,我有size_t但没有size_type。这是怎么回事? - Baz
@Baz,我在我的答案中附加了一篇文章链接:非常值得一读。但是请注意,正如juanchopanza在问题评论中所述,为什么需要传递大小?我从未这样做过。我会传递数据容器的常量引用。 - Bathsheba

1
那是一个奇怪的界面,因为
printIfNotEmpty("Baz", 37);

这样做没有太多意义。

如果你真的对不同容器的状态感兴趣,将其作为参数传递。
如果你想处理不同类型的容器,请使用模板。

template<typename T>
void printIfNotEmpty(const std::string& name, const std::vector<T>& collection)
{
    if (!collection.empty())
    // ...
}

甚至更加普遍
template<typename Collection>
void printIfNotEmpty(const std::string& name, const Collection& collection)
{
    if (!collection.empty())
    // ...
}

-1

不,你需要传递std::vector<T>::size_type,其中T是你的对象类型。

对于第二个问题,size_type是一个typedef(变量类型的别名),它在向量容器类中进行了命名空间处理。


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