模板签名问题

时间:2011-02-07 23:02:41

标签: c++ templates

我是新手使用模板,我需要使用模板做某事,但不知道如何调用模板化函数。它可能很简单,但我看不到它。

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

3 个答案:

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

希望这更容易阅读和写作!