Почему я не могу сравнить<boost::function>объектов с<operator==>или<operator!=>?
Сравнение между<boost::function>объектами не может быть реализовано «хорошо», а потому не будет реализовано. Типичная семантика, требуемая для<f ==
g><boost::function><f>и<g>являются:
Если<f>и<g>сохраняют функции объектов одного и того же типа, используйте<operator==>этого типа для сравнения их.
Если<f>и<g>хранят функциональные объекты разных типов, то возвращают<false>.
Проблема возникает, когда тип объектов функции, хранящихся как<f>, так и<g>, не имеет<operator==>: Мы хотели бы, чтобы выражение<f ==
g>не компилировалось, как это происходит, например, со стандартными контейнерами. Однако для<boost::function>это неосуществимо, потому что оно обязательно «стерегает» некоторую информацию типа после того, как ему назначен объект функции, поэтому он не может попытаться позвонить<operator==>позже: он должен либо найти способ позвонить<operator==>сейчас, либо он никогда не сможет позвонить позже. Обратите внимание, например, что произойдет, если вы попытаетесь поместить значение<float>в объект<boost::function>: вы получите ошибку в операторе назначения или конструкторе, а не в<operator()>, потому что выражение вызова функции должно быть связано в конструкторе или операторе назначения.
Наиболее перспективным подходом является поиск способа определения того, можно ли вызвать конкретный тип<operator==>, а затем поддерживать его только тогда, когда он доступен; в других ситуациях было бы брошено исключение. Однако на сегодняшний день не существует известного способа определить, правильно ли определено произвольное операторское выражение<f == g>. Лучшее из известных решений имеет следующие нежелательные качества:
Для объектов, где<operator==>недоступно (например, потому что это<private>).
При звонке по телефону (30) не получается.
При этом, если<operator==>заявление является правильным, то<operator==>не может быть составлено.
Все эти проблемы переводятся в сбои в<boost::function>конструкторах или операторе присваивания,, даже если пользователь никогда не вызывает оператора ==. Мы не можем так поступать с пользователями.
Другой вариант — возложить бремя на пользователей, которые хотят использовать<operator==>, например, предоставив<is_equality_comparable>черту, на которую они могут специализироваться. Это осуществимое решение, но на практике оно опасно, потому что забывание специализироваться на этом признаке приведет к неожиданным исключениям из<boost::function><operator==>. Это, по существу, сводит на нет полезность<operator==>в контексте, в котором она наиболее желательна: многоцелевой обратный вызов. У библиотекиСигналовесть способ обойти это.
2.
Я вижу пустые указатели, это безопасно?
Да,<boost::function>тип безопасен, хотя он использует указатели пустоты и указатели для функций, возвращающих пустоту и не принимающих никаких аргументов. По сути, вся информация типа кодируется в функциях, которые управляют и вызывают указатели функций и объекты функций. Только эти функции инстанцируются с точным типом, на который указывает указатель пустоты или указатель на функцию пустоты. Причина, по которой оба требуются, заключается в том, что можно безопасно отбрасывать между указателями пустоты и указателями объектов или между различными типами указателей функций (при условии, что вы не вызываете указатель функции с неправильным типом).
3.
Почему существуют обходные пути для возврата пустоты? C++ позволяет это делать!
Возврат пробелов разрешен стандартом C++, как в этом фрагменте кода:
void f();
void g() { return f(); }
Это действительное использование<boost::function>, потому что не используются возвраты. С возвратом пустоты мы попытаемся составить плохо сформированный код, похожий на:
int f();
void g() { return f(); }
В сущности, не использование возвратов пустоты позволяет<boost::function>проглотить возвращаемое значение. Это согласуется с тем, что пользователь может назначать и вызывать функции и объекты с параметрами, которые точно не совпадают.
4.
Почему (функция) клонирование?
В ноябре-декабре 2000 года вопрос о клонировании и подсчете ссылок долго обсуждался, и было решено, что клонирование дает более предсказуемую семантику. Я не буду пересказывать здесь дискуссию, но если клонирование некорректно для конкретного приложения, можно использовать референс-счетчик.
Стоимость<boost::function>может быть разумно последовательно измерена на уровне около 20 нс + / - 10 нс на современной платформе >2 ГГц по сравнению с прямым наложением кода.
Тем не менее, производительность вашего приложения может извлечь выгоду из<boost::function>в зависимости от того, как оптимизируется ваш оптимизатор C++. Подобно стандартному указателю функции, различия порядка 10% были отмечены в пользу или недостаток использования<boost::function>для вызова функции, которая содержит узкий цикл в зависимости от обстоятельств компиляции.
Статья Frequently Asked Questions раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 13. Boost.Function может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.