У меня есть устаревшая функция Foo
, которая принимает два итератора в качестве входных данных, и я хочу использовать ее повторно, но не должен менять ее интерфейс (хотя я могу изменить тип итераторов, но не могу сделать это шаблоном)
проблема в том, что у меня есть итераторы другого типа, и мне нужно скопировать исходный контейнер, чтобы получить итераторы, необходимые для Foo
функции
Мне было интересно, есть ли способ преобразовать итераторы одного типа в итераторы другого типа?
Iпытался использовать boost::make_transform_iterator
, но он не скомпилируется, говоря, что итераторы бывают разных типов
Можно ли раскомментировать и использовать option 2
(см. код ниже)?
#include <algorithm>
#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
#include <boost/iterator/transform_iterator.hpp>
/* Method with fixed interface */
void Foo(std::vector<int>::const_iterator beginIt, std::vector<int>::const_iterator endIt)
{
std::cout << "ints:" << std::endl;
std::copy(beginIt, endIt, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
int main()
{
const std::vector<std::string> strings { "2", "4", "6" };
auto convertStringToInt = [](const std::string & s) { return std::stoi(s); };
// 1) Works, but creates another container with size of initial container
std::vector<int> convertedInts;
std::transform(strings.begin(), strings.end(), std::back_inserter(convertedInts), convertStringToInt);
Foo(convertedInts.begin(), convertedInts.end());
// 2) Doesn't compile, but operates only with iterators hence there's minimum overhead
//auto beg = boost::make_transform_iterator(strings.begin(), convertStringToInt);
//auto end = boost::make_transform_iterator(strings.end(), convertStringToInt);
//Foo(beg, end);
std::cout << "strings:" << std::endl;
std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, " "));
}
Код можетбыть скомпилированным в онлайн-компиляторе wandbox (у него нет функции «поделиться»)
Редактировать: Foo
реализует логику, строго специфичную для int
Так что сделать его непатентованным невозможно. Но у меня есть контейнер (из std::string
как в примере), элементы которого я могу преобразовать в целые с помощью лямбды без захвата.
Кажется очень странным, что не существует стандартного способа обернуть один итератор в другой :)