查找最大容器大小 C++
Find maximum container size C++
我正在尝试为以下问题找到一个好的解决方案:
我想实现一个函数,它接受可变数量的容器参数和 returns 最大容器的大小。这是一个例子:
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
应该 return 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 的东西,我在问自己是否有更好的方法来实现它。也许通过使用一些 class 和重载 operator<<()
所以我可以输入这样的东西:
MaxSizeFinder cFinder;
cFinder << vStr << vInt << vDouble << lChar;
size_t uiMaxSize = cFinder.getResult();
你觉得这样的事情有可能吗?有什么建议么?
谢谢。
使用可变参数模板:
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
的格式说明符)。
最后,根据评论,return 类型已更改为签名类型,主要充当 size_t
的签名对应类型(有点像 non-standard ssize_t
).
对于 future-proof 的答案,很快就会有一个 std::size
获取容器大小的更通用的方法:
using std::size;
return std::max({size(conts)...});
这与上面的扩展类似:size(conts1), size(conts2), ..., size(contsN)
*通常,参数包与T&&...
一起使用,而std::forward
而不是const T&...
。当使用的对象是右值时,这可能会给您带来 third-party 类 具有更高效 size
功能的东西。但是,它通常会增加复杂性,从而降低获得任何好处的机会。
我正在尝试为以下问题找到一个好的解决方案:
我想实现一个函数,它接受可变数量的容器参数和 returns 最大容器的大小。这是一个例子:
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
应该 return 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 的东西,我在问自己是否有更好的方法来实现它。也许通过使用一些 class 和重载 operator<<()
所以我可以输入这样的东西:
MaxSizeFinder cFinder;
cFinder << vStr << vInt << vDouble << lChar;
size_t uiMaxSize = cFinder.getResult();
你觉得这样的事情有可能吗?有什么建议么?
谢谢。
使用可变参数模板:
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
的格式说明符)。
最后,根据评论,return 类型已更改为签名类型,主要充当 size_t
的签名对应类型(有点像 non-standard ssize_t
).
对于 future-proof 的答案,很快就会有一个 std::size
获取容器大小的更通用的方法:
using std::size;
return std::max({size(conts)...});
这与上面的扩展类似:size(conts1), size(conts2), ..., size(contsN)
*通常,参数包与T&&...
一起使用,而std::forward
而不是const T&...
。当使用的对象是右值时,这可能会给您带来 third-party 类 具有更高效 size
功能的东西。但是,它通常会增加复杂性,从而降低获得任何好处的机会。