在函数中,我需要区分左值和右值引用,因此明显的路径是重载:
void myfunc(A&& a);
void myfunc(const A& a);
这完全具有所需的行为,具有明确定义的类型和隐式转换。但是有太多的代码重复,我更愿意将相关决策封装在里面,只保留一个函数,因此通过通用引用传递可能是一种选择:
template <typename A> void myfunc(A&& a);
然而,这有一个不幸的缺点,现在任何对象都可以作为第一个参数传递,因此可以通过 enable_if 施加约束:
template <typename T, class = typename enable_if<
is_same<typename remove_const<typename remove_reference<T>::type>::type, A>::value,
T>::type>
void myfunc( T&& a);
这似乎可以完成这项工作,但是(我猜已经通过模板化了)我们失去了一个很好的重载属性,它可以触发隐式转换构造函数到类型 A(比如从类型 C 参数)。重载不是一个选项,因为某些函数可能有 3 个或更多 A&& 参数,无意处理组合爆炸。可以以某种方式恢复隐式转换吗?当然,一种解决方法可能是例如为 A 添加其他允许的参数类型,并在主函数中执行任何需要的转换,但这是侵入性的、丑陋的、显式隐含并产生混淆(原始 C 参数可能是左值 [参考]并通过转换产生一个右值)。有更好的办法吗?