Множество библиотек 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(int units)
в качестве функции-члена c. Если поведение должно быть получено из пространства имен объекта, оно, вероятно, будет выглядеть как MoveForward(const Car & car_, int units)
. Давайте определим функцию, которая хочет отправить mover(NS::direction d, const NS::vehicle & v_)
, где direction — это перечисление, а v_ — это базовый класс NS::car
.
operator<<
в своем классе для вывода в поток. Оператор-член должен иметь класс слева от оператора, а не справа. Кроме того, поиск имени является частью компилятора, а не библиотеки, и будет включать шаблоны только в том случае, если задействован класс шаблона или функция шаблона. Если вы спрашиваете, как выполняется поиск имени, уточните свой вопрос. В противном случае, я не знаю, о чем вы спрашиваете. - person David Thornley   schedule 14.03.2011operator<<
. Я удалил пример, но кто-то редактировал мой вопрос и перезаписал удаление :D - person Hassan Syed   schedule 14.03.2011