我正在努力为以下问题找到一个好的解决方案:
我想实现一个函数,它接受可变数量的容器参数并返回最大容器的大小。这是一个例子:
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();
你觉得这样的事情有可能吗?有什么建议?
谢谢。
答案 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
函数的第三方类。然而,它增加了复杂性,因为任何好处的可能性都很低。