Механика расширения с помощью бесплатных функций или функций-членов

Множество библиотек C ++, включенных в стандарт, позволяют вам адаптировать ваши объекты для использования в библиотеках. Часто выбор бывает между функцией-членом или свободной функцией в том же пространстве имен.

Я ' Я хочу знать механизмы и конструкции, которые код библиотеки использует для отправки вызова, который будет вызывать одну из этих «расширенных» функций, я знаю, что это решение должно быть принято во время компиляции и включает шаблоны. Следующий псевдокод времени выполнения невозможен / бессмысленен, причины выходят за рамки этого вопроса.

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"

Приведенный выше код выглядит как код времени выполнения: /. Итак, как библиотека определяет пространство имен, в котором находится класс, как она определяет три условия, какие еще подводные камни следует избегать.

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

!! ВЫИГРАТЬ НАГРАД !!

Итак, согласно ответу Стива (и комментариям), ADL и SFINAE являются ключевыми конструкциями для подключения диспетчеризации во время компиляции. У меня голова вокруг ADL (примитивно) и SFINAE (опять примитивно). Но я не знаю, как они организуются вместе так, как я думаю, они должны.

Я хочу увидеть наглядный пример того, как эти две конструкции могут быть объединены, чтобы библиотека могла выбирать во время компиляции, вызывать ли Предоставляемая пользователем функция-член в объекте или предоставляемая пользователем бесплатная функция, предоставляемая в пространстве имен того же объекта. Это должно выполняться только с использованием двух приведенных выше конструкций, без какой-либо диспетчеризации во время выполнения.

Допустим, рассматриваемый объект называется NS :: Car , и этот объект должен обеспечивать поведение MoveForward (целые единицы) , как функция-член ofc. Если поведение должно быть взято из пространства имен объекта, оно, вероятно, будет выглядеть как MoveForward (const Car & car_, int units) . Давайте определим функцию, которая хочет отправить mover (NS :: direction d, const NS :: vehicle & v _) , где direction - это перечисление, а v_ - базовый класс NS :: автомобиль .

10
задан Hassan Syed 23 March 2011 в 12:05
поделиться