函数重载,无法减少模板参数

时间:2012-10-01 06:59:05

标签: c++ templates stl iterator overloading

我正在尝试重载一个Sum函数,该函数接受[list或vector] start和end迭代器作为参数。这个编译错误让我很困惑。相关代码如下:

template <typename T1, typename T2>
const double Sum(const typename T1::const_iterator& start_iter, const typename T2::const_iterator& end_iter)
{// overloaded function that calculates sum between two iterators
    typename T1::const_iterator iterator_begin = start_iter;
    typename T2::const_iterator iterator_end = end_iter;

    double my_sum = 0;

    for (iterator_begin; iterator_begin != iterator_end; iterator_begin++)
        my_sum += *iterator_begin;

    return my_sum;      
}

int main()
{

list<double> test_list(10,5.1);
cout << Sum(test_list.begin(), test_list.end()); // compiler errors here

}

我收到以下编译错误:

  

iterators.cpp(72):错误C2783:'const double Sum(const   T1 :: const_iterator&amp;,const T2 :: const_iterator&amp;)':无法推断   'T1'的模板参数

     

iterators.cpp(72):错误C2783:'const double Sum(const   T1 :: const_iterator&amp;,const T2 :: const_iterator&amp;)':无法推断   'T2'的模板参数

     

iterators.cpp(72):错误C2780:'const double Sum(const   std :: map&amp;)':需要1个参数 - 提供2个

     

iterators.cpp(72):错误C2780:'const double Sum(const T&amp;)':   期望1个参数 - 提供2个

编译器如何识别我试图用两个输入调用Sum函数?我正在调用该函数错误?

谢谢!

3 个答案:

答案 0 :(得分:5)

你不需要告诉它迭代器必须是某些类型T1T2的成员,只需在迭代器类型本身上模板化它:

template <typename Iter>
const double Sum(Iter iterator_begin, Iter iterator_end)
{
    double my_sum = 0;
    for (; iterator_begin != iterator_end; ++iterator_end)
        my_sum += *iterator_begin;
    return my_sum;      
}

int main()
{
    std::list<double> test_list;
    std::cout << Sum(test_list.begin(), test_list.end());
    return 0;
}

还有一个标准的std::accumulate可以做到这一点:

int main()
{
    std::list<double> test_list;
    std::cout << std::accumulate(test_list.begin(), test_list.end(), 0.0);
    return 0;
}

答案 1 :(得分:4)

首先,我认为你不想这样做。并非所有序列都有 底层容器。 (例如,想想istream_iterator s。)和 更重要的是,你明显允许(甚至鼓励) 从不同的容器开始和结束迭代器;有没有的情况 您可以在T1T2合法使用此功能的地方 不同种类。模板应该有一个参数,即 应该是一个迭代器;按照惯例,对...的约束 迭代器应该以参数的名称表示,例如 InputIterator(此处为案例),ForwardIterator等。

至于你的代码无法编译的原因:

  

在大多数情况下,使用的类型,模板和非类型值   组成P参与模板参数推导。就是他们   可用于确定模板参数的值,以及   如此确定的值必须与确定的值一致   别处。然而,在某些情况下,价值却没有   参与类型推导,但改为使用模板的值   在别处推断或明确指定的参数。   如果模板参数仅在非推导的上下文中使用,则为   未明确指定,模板参数推断失败。

     

未推断的上下文是:

     

- 使用a指定的类型的嵌套名称说明符   合格-ID。

     

[...]

(来自§14.8.2.5/ 4,5。)

答案 2 :(得分:2)

像这样调用方法..

Sum<list<double>,list<double> >(test_list.begin(), test_list.begin());