【发布时间】:2017-12-10 03:12:34
【问题描述】:
我有一组名为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
如何防止这种无限递归?我是否正确地解决了这个问题?
【问题讨论】:
-
相关:stackoverflow.com/questions/30561407/… -- 将参数放在一个元组中,然后使用 std::get() 以“正确”的顺序将它们拉出。
-
与狭窄的范围分开,我预计在许多情况下需要这样做是代码异味。例如,A 和 B 是否应该不实现形状接口/从父类继承?
-
拥有一个由你的两个类实现的接口不是有意义的吗,所以你真的不需要关心 A 类和 B 类吗?或者这在 C++ 中不是那么容易吗?
标签: c++ templates metaprogramming