Все выглядит великолепно. Однако мы знаем, что «бесплатного сыра не бывает». Расплачиваться приходится эффективностью: вызов предиката выполняется для каждого элемента контейнера — каждый раз формируется стек параметров, функция вызывается, а потом выполняется возврат из нее. Для больших контейнеров это может стать серьезной проблемой. Для повышения эффективности вызовов в С++ используют ключевое слово inlinе. Тело функции, объявленной с этим ключевым словом, может быть подставлено на место вызова — экономится время на заполнение стека, вызов функции и возврат из нее. Как правило, предикаты — это простые функции, поэтому являются хорошими кандидатами на подстановку. Но в данном случае объявлять предикаты подставляемыми бесполезно, так как вызов является не прямым, а косвенным — через указатель. Компилятор не может подставить функцию, вызов которой является косвенным.
Есть еще одна, более важная причина, по которой нельзя считать нашу функцию-фильтр copy_if () достаточно универсальной: мы не можем передать функции-фильтру предикат-метод. Дело в том, что указатель на метод существенно отличается по типу от обычного указателя на функцию, даже если прототипы функции и метода внешне идентичны. Вспомним, как определяется указатель на функцию:
тип (*имя-указателя)(список параметров); Для сокращения записи применяют обычно оператор typedef. Следующее объявление вводит новое имя типа:
typedef тип (*тип-указателя)(список параметров);
После этого указатель на функцию можно объявлять так:
тип-указателя имя-указателя;
Указателю присваивается адрес функции. В С++ разрешается присваивать адрес функции, явно или неявно задавая операцию получения адреса:
В последнем случае имя функции неявно преобразуется в адрес. ПРИМЕЧАНИЕ
В системе Visual C++.NET 2003 для библиотечных функций работает только вариант с явной операцией адресации. Второй вариант вызвал фатальную ошибку компилятора fatal error 1001: intERNAL COMPILER ERROR. Borland С++ Builder 6 оба вызова обрабатывает правильно.
Опубликовал Kest
December 26 2013 19:55:47 ·
4 Комментариев ·
3853 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Сергей December 27 2013 11:48:33
Очень понравилось такое решение. Теперь для большей эффективности вызовов в С++ буду использовать ключевик inlinе. Намного удобнее поставить функцию на место вызова! Это же так экономт время, в несколько раз быстрее заполнится стек, вызов и возврат из функции. Очень помогла эта информация. Спасибо!
Nika December 29 2013 21:00:49
Преподавали мне С++ в университете.Эх мои бы нынешние знания туда сейчас)))Тело функции,объявленное с использованием ключевого слово inlinе можно и поставить на ключевое место - чудесно экономится место.Очень помогла информация.Узнала важные и нужные вещи для себя, а главное своевременно.Большое спасибо!
Макс December 31 2013 07:28:10
так давно не встречался с С++ что уж и думал извили его. да вот оказалось он жив, да в придачу ещё и развивается. таких элегантных решений раньше не было. всё было топорно и рубили как с плеча. буду теперь сюда заходить поновой учить основу основ. а то такой провал в знаниях. да и преподавали в ВУЗах не понимая что эт такое. а в какой среде посоветуете работать?
Павел January 14 2014 07:23:31
Сергей, на счет ключевика inline вы правы, но учитывайте что за более высокую скорость вы платите ростом размера самого кода в конечном виде.
Хотя это не так актуально при нынешних размерах носителей, но все же забывать это не нужно, особенно когда код довольно сложен и обширен.
Кроме того это усложняет его в динамике исполнения.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.