Шаблоны в C ++ и стандартный алгоритм

Проходя книгу «Эффективный STL», автор приводит пример того, как copy_ifможет быть написано, так как это не существует в стандартных алгоритмах. Вот версия авторов:

template <typename Input, typename Output,typename Predicate>
OutputIterator copy_if(Input begin , Input end, Output destBegin, Predicate p)
{
while(begin != end)
{
if(p(*begin)) *destBegin++=*begin;
++ begin;
}
return destBegin;
}

Теперь мой вопрос: как автор может использовать этот метод следующим образом:

copy_if(widg.begin(),widg.end(),ostream_iterator<widg>(cerr,"\n"),isDefective);

У меня вопрос, почему параметры шаблона не определяются с помощью copy_if (так как для этого требуется 3), например

copy_if<p1,p2,p3>(...)

1

Решение

За функция такие шаблоны, как copy_if, компилятор может определить типы параметров шаблона из параметров функции. Вы не должны поставлять их самостоятельно, хотя я не думаю, что это ошибка, если вы это сделаете.

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

5

Другие решения

Параметры типа шаблона функции могут быть выведены компилятором из параметров функции. Например:

template<typename T>
auto return_value_type_instance(const std::vector<T>&) -> T
{
return T();
}

Это пример завершающего возвращаемого типа в C ++ 11, тип возвращаемого значения будет bool если вы передадите std::vector<bool> экземпляр функции, символ, если вы передаете вектор символа и т.д .:

int main()
{
std::vector<bool> a;
std::vector<char> b;
std::vector<float> c;

bool  aa = return_value_type_instance(a);
char  bb = return_value_type_instance(b);
float cc = return_value_type_instance(c);
}

Или, в более распространенном примере, STL-подобные алгоритмы:

template<typename iterator_type>
void print_range(iterator_type begin , iterator_type end)
{
for(iterator_type it = begin ; it != end ; ++it)
std::cout << *it << std::endl;
}

int main()
{
std::vector<int> v = {0,1,2,3};

print_range(v.begin() , v.end());
}

Выход:

0
1
2
3

0