在函数中我需要区分左值和右值引用,所以明显的路径是重载:
void myfunc(A&& a);
void myfunc(const A& a);
Run Code Online (Sandbox Code Playgroud)
这具有完全所需的行为,具有良好定义的类型和隐式转换.然而,代码重复太多,我宁愿将相关决策封装在内部,只保留一个函数,因此通过通用引用可能是一个选项:
template <typename A> void myfunc(A&& a);
Run Code Online (Sandbox Code Playgroud)
然而,这有一个令人遗憾的缺点,即现在任何对象都可以作为第一个参数传递,因此可以通过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);
Run Code Online (Sandbox Code Playgroud)
这几乎似乎可以完成这项工作,但是(我想已经通过模板化)我们已经失去了一个很好的重载属性,可以触发隐式转换构造函数到类型A(比如来自类型C参数).重载不是一个选项,因为某些函数可能有3个或更多A &&参数,无意处理组合爆炸.隐式转换可以以某种方式恢复吗?当然,一种解决方法可能是例如为A添加其他允许的参数类型,并在main函数中执行任何所需的转换,但这是侵入性的,丑陋的,明确的含义并产生混淆(原始C参数可能是左值[reference]并通过转换产生右值).有更好的方法吗?