Загрузка библиотек С++ с включенным стандартом позволяет вам адаптировать ваши объекты для использования в библиотеках. Выбор часто происходит между функцией-членом или свободной функцией в том же пространстве имен.
Я хотел бы знать механику и строить код библиотеки для отправки вызова, который вызовет одну из этих функций расширения, я знаю, что это решение должно иметь место во время компиляции и включает в себя шаблоны. Следующий псевейкод во время выполнения невозможен/не имеет смысла, причины не входят в сферу применения этого вопроса.
if Class A has member function with signature FunctionSignature
choose &A.functionSignature(...)
else if NamespaceOfClassA has free function freeFunctionSignature
choose freeFunctionSignature(...)
else
throw "no valid extension function was provided"
Вышеприведенный код выглядит как код времени выполнения:/. Итак, как библиотека вычисляет пространство имен, в котором находится класс, как он обнаруживает три условия, какие другие подводные камни существуют, которых следует избегать.
Мотивация моего вопроса заключается в том, чтобы иметь возможность находить блоки отправки в библиотеках и иметь возможность использовать конструкции в моем собственном коде. Таким образом, подробные ответы помогут.
!! ДЛЯ WIN BOUNTY!!
Хорошо, поэтому в соответствии с ответом от Стива (и комментариев) ADL и SFINAE являются ключевыми конструкциями для подключения рассылки во время компиляции. У меня есть голова вокруг ADL (примитивно) и SFINAE (опять-таки рудиментарная). Но я не знаю, как они сориентируются вместе так, как мне кажется.
Я хочу увидеть иллюстративный пример того, как эти две конструкции могут быть собраны вместе, чтобы библиотека могла выбирать во время компиляции, следует ли вызывать функцию, предоставленную пользователем пользователем в объекте, или предоставленную пользователем бесплатную функцию, поставляемую в том же пространство имен объектов. Это должно быть сделано только с помощью двух построенных выше конструкций, никакой диспетчеризации без выполнения.
Допустим, что объект, о котором идет речь, называется NS::Car
, и этот объект должен обеспечивать поведение MoveForward(int units)
в качестве функции-члена из c. Если поведение должно быть выбрано из пространства имен объектов, оно, вероятно, будет выглядеть как MoveForward(const Car & car_, int units)
. Позволяет определить функцию, которая хочет отправить mover(NS::direction d, const NS::vehicle & v_)
, где направление является перечислением, а v_ является базовым классом NS::Car
.