我是新手使用模板,我需要使用模板做某事,但不知道如何调用模板化函数。它可能很简单,但我看不到它。
template<class It, class T>
// iterator and value_type of *It
void Calc(It begin, It end, std::pair<int, int> &out)
{
std::vector<It>::iterator iter;
std::map<int, int> StartMap;
std::map<int, int>::reverse_iterator rit;
int sum, start, stop, count;
start = stop = 1;
count = sum = 0;
for(iter = begin; iter != end; iter++ )
{
sum += iter;
count++;
stop++;
if(sum <= 0)
{
// store original start
StartMap.insert(start, count);
// set new start position
start = stop;
}
}
// set iterator to highest value
rit = StartMap.rbegin();
start = rit->first;
stop = start + rit->second;
out.insert(start, stop);
}
但不确定如何用2 std :: vector迭代器调用它。 我试过这个
void doSomething(std::vector<int>& stopsVec)
{
std::pair<int, int> out;
Calc<std::vector<int>::iterator, std::pair<int, int>>(stopsVec.begin(), stopsVec.end(), &out);
}
答案 0 :(得分:4)
void doSomething(std::vector<int>& stopsVec)
{
std::pair<int, int> out;
Calc<std::vector<int>::iterator, std::pair<int, int> >
(stopsVec.begin(), stopsVec.end(), out); // not &out
}
Calc
会引用std::pair<int, int>
,因此您只想提供out
。传递&out
尝试将指针传递给一对 - 这将无效。
修改强>
假设签名实际上是:
template<class It>
void Calc(It begin, It end, std::pair<int, int> &out)
您可以使用以下方式调用它:
Calc(stopsVec.begin(), stopsVec.end(), out);
编译器可以从参数中推导出正确的模板类型,而无需您在<>
修改强>
基思在下面提出了一个很好的观点。这是你在这里遇到的另一个编译错误。另请注意:
sum += iter;
没有做你想要的。你可能意味着:
sum += *iter;
但由于sum
是一个int,而iter
是一个模板类型,因此这不是一个通用的模板方法。它实际上只适用于数字类型的迭代器。
另外还有一个问题:
Calc<std::vector<int>::iterator, std::pair<int, int> > // use a space
(stopsVec.begin(), stopsVec.end(), out);
而不是
Calc<std::vector<int>::iterator, std::pair<int, int>> // ">>" is shift operator
(stopsVec.begin(), stopsVec.end(), out);
在结束>
符号之间需要一个空格才能拥有模板语法。否则你正在进行bithift(或流提取),编译器会感到困惑,因为从那一点开始没有任何意义。
答案 1 :(得分:0)
请注意:
template<class It, class T>
void Calc(It begin, It end, std::pair<int, int> &out)
{
std::vector<It>::iterator iter;
for(iter = begin; iter != end; iter++ )
错了。应该是:
template<class It, class T>
void Calc(It begin, It end, std::pair<int, int> &out)
{
It iter;
// etc.
for(iter = begin; iter != end; iter++ )
但是请注意,在C ++中,通常首选遵循'声明是初始化'方法,因此这变为:
template<class It, class T>
void Calc(It begin, It end, std::pair<int, int> &out)
{
// etc.
for(It iter = begin; iter != end; iter++ )
答案 2 :(得分:0)
您不需要将迭代的类型显式传递为模板参数。 STL设计人员非常明智并且意识到这经常出现,并且有一种(不是非常漂亮但完全正确)的方式来反省迭代器的类型以获得它的基础类型如下:
typedef typename std::iterator_traits<It>::value_type value_type;
完成此操作后,可以使用名称value_type来引用要迭代的类型。这允许您将模板函数重写为
template <typename It>
void Calc(It begin, It end, std::pair<int, int>& out) {
typedef typename std::iterator_traits<It>::value_type value_type;
/* ... Rest of the code, now using this type ... */
}
为了达成协议,既然没有任何辅助类型,你可以直接调用该函数
std::vector<int> v = /* ... */
std::pair<int, int> result;
Calc(v.begin(), v.end(), result);
希望这更容易阅读和写作!