1

我正在尝试重载 Sum 函数,该函数接受 [list or vector] 开始和结束迭代器作为参数。这个编译器错误真的让我很困惑。相关代码如下:

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 &,const T2::const_iterator &)' : 无法推导出 'T1' 的模板参数

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

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

iterators.cpp(72): error C2780: 'const double Sum(const T &)' : 需要 1 个参数 - 提供 2 个

编译器如何无法识别我正在尝试使用两个输入调用 Sum 函数?我错误地调用了该函数?

谢谢!

4

3 回答 3

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;
}
于 2012-10-01T07:12:33.253 回答
4

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

至于为什么您的代码无法编译:

在大多数情况下,用于构成 P 的类型、模板和非类型值参与模板参数推导。也就是说,它们可用于确定模板参数的值,并且如此确定的值必须与其他地方确定的值一致。然而,在某些情况下,该值不参与类型推导,而是使用在其他地方推导或明确指定的模板参数的值。如果模板参数仅在非推导上下文中使用且未明确指定,则模板参数推导失败。

未推断的上下文是:

— 使用限定 ID 指定的类型的嵌套名称说明符。

[...]

(来自§14.8.2.5/4,5。)

于 2012-10-01T07:38:14.893 回答
2

像这样的调用方法..

Sum<list<double>,list<double> >(test_list.begin(), test_list.begin());
于 2012-10-01T07:06:13.947 回答