Невероятно быстрые делегаты C ++ и разные переводы
-
20-09-2019 - |
Вопрос
По словам Сергея Рьязанов, его Невероятно быстрые делегаты C ++ не сопоставимы:
Мои делегаты нельзя сравнить. Операторы сравнения не определены, потому что делегат не содержит указателя на метод. Указтер на функцию заглушки может отличаться в различных компиляционных единицах.
На какой читатели ответили:
«Указатель на функцию заглушки может быть различным в различных компиляционных единицах». Afaik, это неправда. Компиляторы обязаны повторно использовать функции шаблонов, генерируемые в различных компиляционных единицах (это я уверен, но я думаю, что Борланд однажды нарушил это правило). Я думаю, что это потому, что классы (не в «безымянных» пространствах имен) используют внешнюю связь, и то, как вы используете функции заглушки Заставит генерируемой версии, не входящей в нет, и «внешняя связь», выполняемая линкером
Если вы определите функцию шаблона один блок перевода (файл CPP), а затем определите одну и ту же функцию по -разному в другой блоке перевода, только одна из двух версий попадет в окончательный исполняемый файл. (Это на самом деле нарушает «правило одного определения», но работает на GCC, по крайней мере ... не уверен в MSVC.) Дело в том, что адрес [заглушки] будет одинаковым в разных единицах.
Я бы призвал вас обновить статью (включая возможность сравнения), если вы обнаружите, что это верно для MSVC - если MSVC является предоставлением стандартов, в этом отношении.
Сейчас этой статье четыре года, и автор не ответил ни на один из комментариев в течение последних трех лет или около того, поэтому мне интересно, есть ли какая -либо заслуга в вышеуказанном комментарии и действительно ли эта конкретная реализация может быть изменена на Поддержка сравнения.
Запрещает ли стандарт C ++ такому использованию такое использование, и если да, то действительно ли какой-либо из недавних компиляторов соответствуют этому отношению?
Решение
Код является как стандартным, так и хорошим. Я не вижу никакого места, где он нарушает ODR, и это правда, что все экземпляры шаблона функции с одинаковыми параметрами шаблона должны иметь «один и тот же адрес» (в некотором смысле, что указатели на функции должны быть одинаковыми) - как Это достигнуто не важно. ISO C ++ 03 14.5.5.1 [temp.over.link] описывает правила более подробно.
Таким образом, сравнение вполне может быть определена там в соответствии с согласованным и портативным способом.
Другие советы
Так называемой заглушка функции в Невероятно быстрые делегаты C ++ находятся Статический шаблон функции членов члена, которые в основном Функции шаблона. Анкет То же самое относится и к улучшенному варианту Невероятно быстрые делегаты C ++, фиксированные.
Итак, вопрос сводится к этому:
Совместны ли экземпляры функции шаблона (с использованием одних и тех же параметров шаблона и определения) в разных единицах перевода одного и того же адреса указателя функции?
Согласно стандарту C ++ (ISO C ++ 17, § 17.5.6.1), ответ да.
Как сказал @Pavel в своем ответе, то же самое применимо для стандарта ISO C ++ 03 (ISO C ++ 03, § 14.5.5.1).
Другими словами, этот подход является стандартным соответствующим, а делегаты безопасно сопоставимы - их данные сравниваются равны тогда и только тогда, когда они связаны с одной и той же функцией и (в случае функций -членов) с одним и тем же объектом.