定义交换操作时减少代码重复 [英] Reducing code duplication while defining a commutative operation

查看:70
本文介绍了定义交换操作时减少代码重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组名为overlap的可交换二进制函数的重载,它接受两种不同的类型:

I have a a set of overloads of a commutative binary function named overlap, which accepts two distinct types:

class A a; class B b;
bool overlap(A, B);
bool overlap(B, A);

当且仅当一种形状与另一种形状重叠时,我的函数overlap返回true-这是讨论多种方法.

My function overlap returns true if and only if one shape overlaps the other - this is one common example used when discussing multimethods.

因为overlap(a, b)等同于overlap(b, a),所以我只需要实现关系的一个边".一种重复的解决方案是编写如下内容:

Because overlap(a, b) is equivalent to overlap(b, a), I only need to implement one "side" of the relation. One repetitive solution is to write something like this:

bool overlap(A a, B b) { /* check for overlap */ }
bool overlap(B b, A a) { return overlap(a, b);   }

但是我不希望通过允许使用模板来生成相同功能的N! / 2普通版本来代替它们.

But I would prefer not to write an extra N! / 2 trivial versions of the same function by allowing them to be generated instead, using a template.

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

Unfortuately, this is prone to recurse infinitely, which is not acceptable: see http://coliru.stacked-crooked.com/a/20851835593bd557

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

How can I prevent such infinite recursion? Am I approaching the problem correctly?

推荐答案

有一个简单的解决方法:

Here's a simple fix:

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

模板本身声明了目标函数,由于它是完全匹配的,因此它比递归更可取(在实际情况下,请务必注意常量性和引用性).如果尚未实现该功能,则会出现链接器错误:

The template itself declares the target function, which will be preferred over recursion because it is an exact match (be sure to take care of constness and reference-ness in your real case). If the function has not been implemented, you get a linker error:

/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

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

... which points directly at the missing function :)

这篇关于定义交换操作时减少代码重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆