template<typename T, int nSize>
T sum(std::array<T, nSize> const&);
будет эквивалентной подписью для std::array
.Как видите, подпись уже отличается.Попытка сделать то же самое для std::vector
обречена на неудачу:
template<typename T, int nSize>
T sum(std::vector<T> const&);
Как вы могли бы узнать уже во время компиляции , сколько элементов будет находиться в векторе ???Вы просто не можете.Даже если вы указали nSize
в коде явно, например, sum<std::vector<int>, 7>
, функция тогда будет всегда пытаться выполнить итерацию ровно по семи элементам, что приведет к неопределенному поведению, если их меньше, и не учитывать лишние, еслиЕсть и другие ...
Типичный путь - использование итераторов начала и конца, как это делает стандартная библиотека для всех своих алгоритмов:
template <typename Iterator>
auto sum(Iterator begin, Iterator end) -> std::remove_reference_t<decltype(*begin)>
{
using type = decltype(sum(begin, end)); // just not wanting to repeat all
// that remove_reference stuff...
type s = type();
for( ; begin != end; ++begin)
{
s += *begin;
}
return s;
}
Вы дополнительноможет, основываясь на этой функции, обеспечить общую перегрузку для произвольных контейнеров:
template <typename Container>
auto sum(Container const& c)
{
using std::begin;
using std::end;
return sum(begin(c), end(c));
}