Проходя книгу «Эффективный 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>(...)
За функция такие шаблоны, как copy_if, компилятор может определить типы параметров шаблона из параметров функции. Вы не должны поставлять их самостоятельно, хотя я не думаю, что это ошибка, если вы это сделаете.
Это отличается от учебный класс шаблоны, где вы должны явно указать параметры шаблона.
Параметры типа шаблона функции могут быть выведены компилятором из параметров функции. Например:
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