2013-10-05 2 views
1

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

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>(...) 
+7

'станд :: copy_if' существует. Это было не так, когда была написана книга. – chris

+1

Как вы можете написать 'std :: cout << std :: endl', а не' std :: operator <<< std :: ostream & (*) (std :: ostream *)> (std :: cout, std: : епсИ) '? –

+0

@KerrekSB - один из лучших примеров. Многие люди не знают, что такое 'std :: endl' и почему' << 'работает, если вы не используете' using namespace std'. Два примера «расширенного» поведения/функций C++ в самой распространенной/простой исходной строке C++. – Manu343726

ответ

5

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

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

+1

На самом деле, рекомендуется STL (и не зря) не указывать их, если у вас нет веских оснований. – chris

+1

@chris: [STL действительно рекомендует его] (http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-), но [стандартная библиотека C++] (http: //stackoverflow.com/a/5205571/596781) также рекомендует его. –

+0

@KerrekSB, Интересно, не знал, что это было так хорошо, но это только хорошо, что он делает. – chris

0

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

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

@chris Он компилирует, но делает неявные преобразования, не так ли? (Это не пункт примера, была опечатка, которую я еще исправил). С другой стороны, первый пример настолько сложный (тип возвращаемого возврата), вот первый пример, который пришел мне на ум. – Manu343726

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

  • Нет связанных вопросов^_^