我有一组名为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)); }

不幸的是,这倾向于无限递归,这是 Not Acceptable :请参阅
http://coliru.stacked-crooked.com/a/20851835593bd557

如何防止这种无限递归?我能正确解决问题吗?

最佳答案

这是一个简单的解决方法:

template <typename T, typename U>
void overlap(T t, U u)
{
    void overlap(U, T);
    overlap(u, t);
}

模板本身声明了目标函数,由于它是完全匹配的,因此将优先于递归,因为它是完全匹配的(在实际情况下,请务必注意常量性和引用性)。如果该功能尚未实现,则会出现链接器错误:
/tmp/cc7zinK8.o: In function `void overlap<C, D>(C, D)':
main.cpp:(.text._Z7overlapI1C1DEvT_T0_[_Z7overlapI1C1DEvT_T0_]+0x20):
    undefined reference to `overlap(D, C)'
collect2: error: ld returned 1 exit status

...直接指向缺少的功能:)

09-27 15:26