如何将向量或 valarray 作为参数传递给 C++ 模板函数
2021-12-13
401
我觉得这可能是一个基本问题,但经过一番搜索,我找不到简单的答案,所以我想问一下。
我有一个函数,用于返回容器中的第 n 个百分位值,但由于遗留原因,数组可以是向量或 valarray,并且可以包含双精度或浮点数。该函数的正确语法是什么? 目前我有:
template <template <class> class vType, class elType>
elType GetPercentile(vType<elType>& vData, double dPercentile)
{
int iOffset = int(dPercentile * vData.size());
std::nth_element(begin(vData), begin(vData) + iOffset, end(vData));
return static_cast<elType>(vData[iOffset]);
}
传递 valarray 时编译成功,但传递向量时编译失败:
'elType GetPercentile(vType &,double)': could not deduce template argument for 'vType &' from 'std::vector<float,std::allocator>'
有办法吗?为两种容器类型复制代码似乎很愚蠢。(如果代码本身有任何评论,那也没问题。)
非常感谢您的任何建议。 Bill H
2个回答
您让模板变得过于复杂。只需这样做即可。无需静态转换。使用自动返回扣除。
另外,您可能不想通过引用传递 vData,因为
std::nth_element
将在部分排序过程中更改调用方的数据。此外,
dPercentile
的命名不当,因为您没有将分数值按 100 缩放。请考虑缩放它或重命名该参数。
#include <vector>
#include <valarray>
#include <algorithm>
template<class vType>
auto GetPercentile(vType vData, double dPercentile)
{
int iOffset = int(dPercentile * vData.size());
std::nth_element(begin(vData), begin(vData) + iOffset, end(vData));
return vData[iOffset];
}
int main()
{
std::vector<float> v{ 1,2,3,4 };
std::valarray<float> va{ 1., 2., 3., 4. };
auto nth_v = GetPercentile(v, .5); //returns 3.f
auto nth_va = GetPercentile(va, .5); //returns 3.f
};
doug
2021-12-13
std::vector
有 2 个模板参数。第二个是分配器,它有一个默认值,因此您通常不会使用它。
但是,在
c++17
之前,模板模板参数仅在模板参数数量相同时才会匹配。在 c++17 中,这稍微放宽了一点,只要其余模板参数具有默认参数,就可以匹配具有更多模板参数的模板。
无论如何,我都会提出一种在两个容器中使用成员类型的解决方案,即
value_type
。
#include <vector>
#include <algorithm>
#include <valarray>
template <class T>
auto GetPercentile(T& vData, double dPercentile)
{
using elType = typename T::value_type;
int iOffset = int(dPercentile * vData.size());
std::nth_element(begin(vData), begin(vData) + iOffset, end(vData));
return static_cast<elType>(vData[iOffset]);
}
int main() {
auto v = std::vector<int>{1,2,3,4,5};
GetPercentile(v, 2);
auto a = std::valarray<int>(5, 5);
GetPercentile(a, 2);
}
super
2021-12-13