У меня есть набор перегрузок коммутативной двоичной функции с именем overlap
, которая принимает два разных типа:
class A a; class B b;
bool overlap(A, B);
bool overlap(B, A);
Моя функция overlap
возвращает true тогда и только тогда, когда одна форма перекрывает другую - это один общий пример, используемый при обсуждении multimethods.
Поскольку overlap(a, b)
эквивалентен overlap(b, a)
, мне нужно только реализовать одну "сторону" отношения. Одно повторяющееся решение - написать что-то вроде этого:
bool overlap(A a, B b) { /* check for overlap */ }
bool overlap(B b, A a) { return overlap(a, b); }
Но я бы предпочел не писать дополнительные N! / 2
тривиальные версии одной и той же функции, разрешив их сгенерировать вместо этого, используя шаблон.
template <typename T, typename U>
bool overlap(T&& t, U&& u)
{ return overlap(std::forward<U>(u), std::forward<T>(t)); }
К сожалению, это подвержено бесконечной рекурсии, что неприемлемо: см. http://coliru.stacked-crooked.com/a/20851835593bd557
Как я могу предотвратить такую бесконечную рекурсию? Я правильно подошел к проблеме?