2013-09-30 3 views
12

Я хочу сделать метод класса, который принимает std :: vector reference в качестве аргумента. Я хочу использовать его с различными типами данных.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){} 

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

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

+0

Да, это способ сделать это. Или вы спрашиваете что-то еще? – jrok

+2

Что с вами не так? – Asaf

+0

Ответ на этот вопрос сам по себе. Просто добавьте, что если кто-то захочет итерации таких векторов, используйте: 'for (typename vector :: const_iterator it = vect.begin(); it! = Vect.end(); ++ it)' –

ответ

22

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

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& - std::vector, вероятно, просто нужен какой-нибудь произвольный контейнер с произвольным доступом.

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

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

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

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

Смежные вопросы