Подтвердить что ты не робот

Быстрые делегаты С++

Мне известно о следующих подходах к делегатам С++:

. Интерфейсы с чистыми виртуальными функциями
, Boost.Function
, Самые быстрые делегаты С++
, Невозможно быстрые делегаты С++
, Быстрые делегаты С++
, Fast С++ Delegate: перезагрузка и многоадресная рассылка Boost.Function

У каждого есть свои плюсы и минусы. Некоторые из них быстрее, некоторые из них более гибкие, некоторые из них более функциональные, некоторые более стандартизированы, а некоторые более портативны, но я лично увлекаюсь третьим: Сергей Рязанов, возможно, не очень быстрые делегаты С++. Проблема в том, что его делегаты не сопоставимы:

Мои делегаты не могут сравниться. Операторы сравнения не определены, потому что делегат не содержит указателя на метод. Указатель на функцию заглушки может быть разным в разных единицах компиляции.

На кого читатели ответили:

"Указатель на функцию заглушки может быть разным в разных единицах компиляции". AFAIK, это не так. Компиляторы должны повторно использовать функции шаблона, сгенерированные в разных единицах компиляции (это я уверен - но я считаю, что Borland однажды нарушила это правило). Я думаю, что это потому, что классы (не в "безымянных" пространствах имен) используют внешнюю привязку, и то, как вы используете функции заглушки, всегда будет препятствовать их встраиванию (хотя это не должно быть проблемой либо в качестве адреса функции будет принудительно генерировать не встроенную версию, а "внешняя связь", выполняемая компоновщиком, устранит все, кроме одной функции с аналогичным именем (они предполагаются и должны быть идентичными стандарту))...

Если вы определяете функцию шаблона одной единицы перевода (файл cpp), а затем по-разному определяете одну и ту же функцию в другой единицы перевода, только одна из двух версий превратит ее в окончательный исполняемый файл. (Это фактически нарушает "правило одного определения", но работает на GCC, по крайней мере... не уверен в MSVC.) Дело в том, что адрес [заглушки] будет одинаковым в разных единицах.

Я бы настоятельно рекомендовал вам обновить статью (включая возможности сравнения), если вы обнаружите, что это верно для MSVC - если MSVC является стандартом, в этом отношении.

Теперь статья составляет четыре года, и автор не ответил ни на один из комментариев за последние три года или около того, поэтому мне интересно, есть ли какая-либо заслуга в вышеупомянутом комментарии и действительно ли эта конкретная реализация для поддержки сравнений. Стандарт С++ специально запрещает такое использование, и если да, то какие-либо из последних компиляторов в действительности соответствуют стандарту в этом отношении?

Спасибо.

4b9b3361

Ответ 1

Код является как стандартным, так и точным. Я не вижу места, где он нарушает ODR, и верно, что все экземпляры шаблона функции с одинаковыми параметрами шаблона должны иметь "тот же адрес" (в смысле, что указатели на функции должны быть равны) - как это не важно. ISO С++ 03 14.5.5.1 [temp.over.link] описывает правила более подробно.

Таким образом, сравнение может быть определено там в соответствии и переносимым образом.