std :: vector как аргумент функции шаблона

Я хочу создать метод класса, который принимает ссылку std :: vector в качестве аргумента, и я хочу использовать его с различными типами данных.

Функция должна выглядеть так:

void some_function(const std::vector & vect){ //do something with vector }

и я хочу использовать его, например:

std::vector<int> v1;
some_function(v1);
std::vector<string> v2;
some_function(v2);

Надеюсь, что я ясно дал понять. Должен ли я сделать такой способ шаблона:

template<class T>
void some_function(std::vector<T> & vect){}

или я могу сделать это по-другому? Если мне нужно, расскажите, как я могу написать этот метод в классе.

Спасибо за помощь!

Ответ 1

Правильный способ для функции template принимать любой std::vector by const& is:

template<typename T, typename A>
void some_func( std::vector<T,A> const& vec ) {
}

второй аргумент - "распределитель", а при некотором расширенном использовании std::vector он не будет использоваться по умолчанию. Если вы просто принимаете std::vector<T>, ваш some_func отклонит std::vector с альтернативными распределителями.

Теперь, есть другие способы приблизиться к этому, что я буду перечислять быстро. Я перечислил их в соотношении "Снижение затрат: выгод" - одно из них, вероятно, то, что вы хотите, а следующее полезно иногда, и после этого я перейду в более сложные дела, которые редко стоит рассматривать (но может быть полезно в некоторых случаях).

Вы можете принять произвольный тип T по T&& затем проверить, будет ли typename std::remove_reference<T>::type - это тип std::vector. Это позволит вам выполнить "идеальную переадресацию" входящего std::vector. Это также позволило бы вам изменить предикат, который вы используете для тестирования, чтобы принять больше, чем просто std::vector: по большей части, const& to std::vector возможно, просто нужен какой-то произвольный контейнер с произвольным доступом.

Смешно причудливым способом было бы сделать двухступенчатую функцию. На втором этапе для типа фиксированного типа T с SFINAE для определения совместимости входящего объекта используется стандартный вид с произвольным доступом (или только диапазон просмотра, если вам не нужен произвольный доступ), первый шаг выводит тип контейнера пройденного типа и вызывает второй шаг в контексте SFINAE (auto some_func(...)->decltype(...)).

Поскольку стирание типа std::vector<T> const& к диапазону со случайным доступом непрерывного T не теряет много функциональности, преимущество состоит в том, что вы могли бы гарантировать, что тело вашей функции точно такое же для std::vector<T> const& и для T[n] и для std::array<T,n>.

Это не большое преимущество, особенно для требуемого шаблона.

может сделать это намного проще, потому что многоступенчатая SFINAE выше будет сворачиваться в несколько требований.