Я определяю функцию fun(parameter)
.Параметр может быть типа std::vector<int>
или int*
.Я хочу, чтобы он суммировал все элементы в векторе / массиве.
Как вы узнали бы количество элементов только с указателем на int
?Обычный способ - передать пару итераторов.
Можете ли вы показать мне пример кода, я никогда не работал с парами?
Вы передаете итератор первомуelement и итератор за последним элементом диапазона, который вы хотите перебрать.В терминологии интервалов это наполовину открыто [first, last)
:
#include <array>
#include <vector>
#include <list>
#include <iostream>
template<typename ForwardIterator>
long sum(ForwardIterator first, ForwardIterator last)
{
long sum{};
while (first != last)
sum += *first++;
return sum;
}
int main()
{
int foo[]{ 1, 2, 3 };
std::cout << sum(std::begin(foo), std::end(foo)) << '\n';
std::array<int, 3> bar{ 1, 2, 3 };
std::cout << sum(bar.begin(), bar.end()) << '\n';
std::vector<int> qux{ 1, 2, 3 };
std::cout << sum(qux.begin(), qux.end()) << '\n';
std::list<int> hugo{ 1, 2, 3 };
std::cout << sum(hugo.begin(), hugo.end()) << '\n';
}
Черт, вы могли бы также иметь эту функцию только с одним параметром:
#include <array>
#include <vector>
#include <list>
#include <iostream>
template<typename ForwardIterator>
long sum(ForwardIterator first, ForwardIterator last)
{
long sum{};
while (first != last)
sum += *first++;
return sum;
}
template<typename T>
long sum(T const &container)
{
return sum(std::begin(container), std::end(container));
}
int main()
{
int foo[]{ 1, 2, 3 };
// please note that the array is passed by reference (no pointer):
std::cout << sum(foo) << '\n';
// sum(&foo[0]); // wouldn't work because there is
// no overload of std::begin() or std::end() for raw pointers
std::array<int, 3> bar{ 1, 2, 3 };
std::cout << sum(bar) << '\n';
std::vector<int> qux{ 1, 2, 3 };
std::cout << sum(qux) << '\n';
std::list<int> hugo{ 1, 2, 3 };
std::cout << sum(hugo) << '\n';
}
Конечно, не изобретайте зановоwheel: std :: аккумулировать
Требования к типу для прямого итератора состоят в том, что он поддерживает операции iterator++
и *iterator++
.Простой указатель также может рассматриваться как прямой итератор, поскольку эти операции допустимы с указателями. LegacyForwardIterator .На самом деле, указатель еще более мощный и может использоваться в качестве итератора произвольного доступа. LegacyRandomAccessIterator
Но для решения вашего первоначального вопроса: помимо перегрузки функции для различных параметров или записи шаблона функции, существует также std::variant<>
начиная с C ++ 17.