找到最大容器大小C ++

时间:2016-01-10 21:20:09

标签: c++ algorithm c++11 stl

我正在努力为以下问题找到一个好的解决方案:

我想实现一个函数,它接受可变数量的容器参数并返回最大容器的大小。这是一个例子:

std::vector<std::string> vStr(2, "foo");
std::vector<int> vInt(1, 123);
std::vector<double> vDouble(3, 1.1);
std::list<char> lChar(4, '*');
// or even more container

size_t uiMaxSize = getMaxContainerSize(vStr, vInt, vDouble, lChar /*, ...*/);

在这种情况下,getMaxContainerSize应返回4,因为lChar的最大尺寸为4。

我已经使用cstdarg实现了此解决方法:

#include <cstdarg>
...
size_t getMaxContainerSize(int iCnt, ... )
{
  size_t uiMaxSize = 0;
  va_list ap;
  va_start(ap, iCnt);
  for(int i=0; i<iCnt; i++)
  {
    size_t uiTempSize = va_arg(ap, size_t);
    uiMaxSize = uiMaxSize<uiTempSize ? uiTempSize : uiMaxSize;
  }
  va_end(ap);
  return uiMaxSize;
}
...
size_t uiMaxSize = getMaxContainerSize( 4, vStr.size(), vInt.size(), vDouble.size(), lChar.size());

但是有了这个,我必须为每个容器键入.size(),我还必须指定容器的数量。我也不喜欢在C ++程序中使用C语言,我问自己是否有更好的方法来实现它。也许通过使用一些类并重载operator<<()所以我可以键入这样的内容:

MaxSizeFinder cFinder;
cFinder << vStr << vInt << vDouble << lChar;
size_t uiMaxSize = cFinder.getResult();

你觉得这样的事情有可能吗?有什么建议?

谢谢。

1 个答案:

答案 0 :(得分:7)

使用可变参数模板:

template<typename... Conts>
std::ptrdiff_t getMaxContainerSize(const Conts&... conts) {
    return std::max({conts.size()...});
}

当您将容器作为参数传递时,编译器将推导出Conts的类型列表。函数的每个参数都是const <deduced type> & *。使用conts.size()...扩展为conts1.size(), conts2.size(), ..., contsN.size(),其中conts#是赋予函数的每个参数。事实证明std::max有一个方便的重载,您可以将其委托给。

可变参数模板相对于C变量函数有几个关键优势:

  • 它们是类型安全的 - 当类型不匹配时,编译器会保证会抱怨,并且您不需要格式字符串或任何内容。
  • 该函数知道传递了多少个参数,您可以使用sizeof...(Conts)来获取它。
  • 进入时参数没有什么特别的变化。在一个可变函数中,char在函数必须选择它时会是int,等等。
  • 使用参数时,您不需要显式指定任何类型。这意味着您可以接受无限多种类型而不是预定义列表(请考虑printf的格式说明符)。

最后,根据评论,返回类型已更改为签名类型,该类型主要充当size_t的签名对应方式(有点像非标准ssize_t)。

为了面向未来的答案,很快就会有一个std::size用于获得容器大小的更通用的方式:

using std::size;
return std::max({size(conts)...});

此扩展类似于上述内容:size(conts1), size(conts2), ..., size(contsN)

*通常情况下,参数包与T&&... std::forward而不是const T&...一起使用。当使用的对象是右值时,这可能会为您提供具有更高效size函数的第三方类。然而,它增加了复杂性,因为任何好处的可能性都很低。