Быстрые делегаты С++
Мне известно о следующих подходах к делегатам С++:
. Интерфейсы с чистыми виртуальными функциями
, Boost.Function
, Самые быстрые делегаты С++
, Невозможно быстрые делегаты С++
, Быстрые делегаты С++
, Fast С++ Delegate: перезагрузка и многоадресная рассылка Boost.Function
У каждого есть свои плюсы и минусы. Некоторые из них быстрее, некоторые из них более гибкие, некоторые из них более функциональные, некоторые более стандартизированы, а некоторые более портативны, но я лично увлекаюсь третьим: Сергей Рязанов, возможно, не очень быстрые делегаты С++. Проблема в том, что его делегаты не сопоставимы:
Мои делегаты не могут сравниться. Операторы сравнения не определены, потому что делегат не содержит указателя на метод. Указатель на функцию заглушки может быть разным в разных единицах компиляции.
На кого читатели ответили:
"Указатель на функцию заглушки может быть разным в разных единицах компиляции". AFAIK, это не так. Компиляторы должны повторно использовать функции шаблона, сгенерированные в разных единицах компиляции (это я уверен - но я считаю, что Borland однажды нарушила это правило). Я думаю, что это потому, что классы (не в "безымянных" пространствах имен) используют внешнюю привязку, и то, как вы используете функции заглушки, всегда будет препятствовать их встраиванию (хотя это не должно быть проблемой либо в качестве адреса функции будет принудительно генерировать не встроенную версию, а "внешняя связь", выполняемая компоновщиком, устранит все, кроме одной функции с аналогичным именем (они предполагаются и должны быть идентичными стандарту))...
Если вы определяете функцию шаблона одной единицы перевода (файл cpp), а затем по-разному определяете одну и ту же функцию в другой единицы перевода, только одна из двух версий превратит ее в окончательный исполняемый файл. (Это фактически нарушает "правило одного определения", но работает на GCC, по крайней мере... не уверен в MSVC.) Дело в том, что адрес [заглушки] будет одинаковым в разных единицах.
Я бы настоятельно рекомендовал вам обновить статью (включая возможности сравнения), если вы обнаружите, что это верно для MSVC - если MSVC является стандартом, в этом отношении.
Теперь статья составляет четыре года, и автор не ответил ни на один из комментариев за последние три года или около того, поэтому мне интересно, есть ли какая-либо заслуга в вышеупомянутом комментарии и действительно ли эта конкретная реализация для поддержки сравнений. Стандарт С++ специально запрещает такое использование, и если да, то какие-либо из последних компиляторов в действительности соответствуют стандарту в этом отношении?
Спасибо.
Ответы
Ответ 1
Код является как стандартным, так и точным. Я не вижу места, где он нарушает ODR, и верно, что все экземпляры шаблона функции с одинаковыми параметрами шаблона должны иметь "тот же адрес" (в смысле, что указатели на функции должны быть равны) - как это не важно. ISO С++ 03 14.5.5.1 [temp.over.link] описывает правила более подробно.
Таким образом, сравнение может быть определено там в соответствии и переносимым образом.