我试图编写一个函数,它将对容器的元素进行求和。这个容器可以是向量、列表、队列等.这就是我尝试模板的原因。
不幸的是,我得到了这个错误:
“c”不是模板
来源:
#include <iostream>
#include <vector>
using namespace std;
template<class C, typename T>
T sum( C<T>::iterator begin, C<T>::iterator end ) {
T s = null;
for (C<T>::iterator it = begin; it != end; it++) {
s += *it;
}
return s;
}
int main()
{
vector<int> v = {5, 9, 0, 11};
cout << sum(v.begin(), v.end()) << endl;
return 0;
}
我做错什么了?我该怎么修呢?
发布于 2013-11-27 14:20:24
您得到的特别错误是因为您需要一个模板参数:
template<template <typename> class C, typename T>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
T sum( C<T>::iterator begin, C<T>::iterator end )
但是,标准容器通常不只是一个模板参数:
template < class T, class Alloc = allocator<T> > class vector
正确地编写这样的函数是有点不平凡的。您可以使用各种模板参数,也可以像标准库那样使用这些参数,并且只专门处理您真正需要的内容:
// <algorithm>
namespace std {
template <class RandomAccessIterator>
void sort (RandomAccessIterator first, RandomAccessIterator last);
}
在您的情况下(假装标准算法库已经没有满足您的需要):
template <typename Iterator>
auto sum(Iterator begin, Iterator end)
-> decltype(*begin+*begin) // the type of summing two of them
{
if (begin == end) throw std::logic_error("....");
auto s = *begin;
++begin;
for (; begin != end; ++begin) {
s += *begin;
}
return s;
}
与原始代码相比,还有一些不同之处:
T s = null;
)。it
)如果添加init
参数,则几乎可以使其成为noexcept
。
template <typename Iterator, typename T>
T sum(Iterator begin, Iterator end, T init)
{
for (; begin!=end; ++begin)
init += *begin;
return init;
}
但只有几乎,因为init += *begin
仍然可以扔。
如果您有这样的签名,顺便说一句,您已经复制了std::accumulate
的签名。
发布于 2013-11-27 14:14:56
您可以用迭代器类型来表示整个过程,并使用iterator_traits
获取value_type:
#include <iterator>
template<typename Iterator>
typename std::iterator_traits<Iterator>::value_type
sum(Iterator begin, Iterator end)
{
using value_type = typename std::iterator_traits<Iterator>::value_type;
value_type s = value_type();
for (Iterator it = begin; it != end; it++) {
s += *it;
}
return s;
}
在现实生活中,使用std::累积
int sum = std::accumulate(v.begin(), v.end(), 0);
https://stackoverflow.com/questions/20244743
复制相似问题