4

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

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 参数可能是左值 [参考]并通过转换产生一个右值)。有更好的办法吗?

4

1 回答 1

5

这就是std::is_convertible存在的原因:

template <typename T, 
          class = typename enable_if<is_convertible<T, A>::value>::type>   
void myfunc( T&&  a);
于 2016-02-15T14:00:29.537 回答