如何将类型约束和隐式转换与C 11通用引用相结合?

在函数中我需要区分左值和右值引用,所以明显的路径是重载:

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添加其他允许的参数类型,并在main函数中执行任何所需的转换,但这是侵入性的,丑陋的,明确的含义并产生混淆(原始C参数可能是左值[引用]但通过转换产生rvalue ).有更好的方法吗?

最佳答案
这就是std::is_convertible存在的原因:

template <typename T, 
          class = typename enable_if<is_convertible<T, A>::value>::type>   
void myfunc( T&&  a);

转载注明原文:如何将类型约束和隐式转换与C 11通用引用相结合? - 代码日志