2011-02-07 46 views
0

我是使用模板的新手,需要使用模板来完成某些操作,但不知道如何调用模板化函数。这可能很简单,但我看不到它。模板签名问题

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); 
} 
+2

你似乎没有使用模板参数`T`。 – Tim 2011-02-07 23:07:46

回答

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); 

您需要以具有模板语法收盘>标志之间的空间。否则,你正在做位移(或流提取),编译器会感到困惑,因为从那时起没有任何意义。

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++) 
0

你并不需要显式传递正在迭代的类型作为模板参数。 STL的设计者是相当明智的意识到,这经常出现,而且有内省的迭代器的类型,以获得它的基本类型如下:a(不是很漂亮,但完全正确)的方式:

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); 

希望这是更容易读写!