Как написать функцию, принимающую std::vector или std::list?

Немного простой вопрос этот, я думаю.

И векторы, и списки имеют функции push и pop, и, что более важно, их можно повторять:

for ( auto value : items )
    ...

Однако std::vector и std::list, похоже, не имеют общего базового класса. Следовательно, возникает вопрос: как мне написать функцию, которая будет принимать одно из них (или вообще любое другое, подходящее для реализации)?

std::list<int> a;
std::vector<int> b;
DoSomething(a);
DoSomething(b);

Я хотел бы сделать это без перегрузки. Если используются шаблоны, они не должны вызывать безумных сообщений об ошибках. Например, следующий код --

int a;
DoSomething(a);

-- должно привести к ошибке компиляции на месте вызова, не где-то внутри шаблона!

У кого-нибудь есть идеи?


person Sod Almighty    schedule 28.06.2013    source источник


Ответы (2)


Комитет по стандартизации C++ попытался внедрить концепции в C++0x (теперь C++11), чтобы решить поднятые здесь проблемы. Они были вынуждены отказаться от них в конце статьи, поэтому нам придется подождать до будущей версии стандарта.

BCCL от Boost предлагает портативное промежуточное решение. Я никогда не пользовался библиотекой, поэтому не могу поручиться ни за, ни против.

person Marcelo Cantos    schedule 28.06.2013
comment
Значит, ближайшие пять лет или около того это просто невозможно? (Кстати, BCCL выглядит слишком сложным) - person Sod Almighty; 28.06.2013

Большинство алгоритмов stl использовали итераторы в качестве уровня абстракции от контейнера.

Например, sort использует 2 итератора произвольного доступа для сортировки:

template <class RandomAccessIterator>
   void sort (RandomAccessIterator first, RandomAccessIterator last);

Большинство алгоритмов можно реализовать с помощью этой идиомы.

В зависимости от алгоритма, который вы планируете реализовать, вам нужно будет выбрать один из 4 типов стандартных итераторов.

Вот ссылка, которая объясняет, какой тип лучше подходит

person tiridactil    schedule 28.06.2013
comment
Значит, мой единственный вариант — принять два экземпляра forward_iterator? Звучит немного неловко для меня. Почему все коллекции не могут иметь базовый класс Iterable с функциями Begin() и End()? Вздох. - person Sod Almighty; 28.06.2013
comment
Большая часть стандартной библиотеки шаблонов (STL) построена на шаблонах, а не на наследовании. Одна из причин, по которой у вас нет Iteratable, заключается в том, что граф наследования должен быть сложным, чтобы вместить 4 типа итераторов. - person tiridactil; 28.06.2013