首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接受lvalue ref或rvalue ref

接受lvalue ref或rvalue ref
EN

Stack Overflow用户
提问于 2014-10-28 14:29:23
回答 2查看 163关注 0票数 3

我想编写一些函数,这些函数将Object作为它们的参数之一,无论是通过lvalue还是rvalue,ref都无关紧要--但肯定不是按值,而是肯定只有Object。看来我有两种选择:

代码语言:javascript
复制
void foo(Object& o) {
    // stuff
}

void foo(Object&& o) { foo(o); } // this is fine for my use-case

或使用通用参考资料:

代码语言:javascript
复制
template <typename T, typename U>
using decays_to = typename std::is_same<std::decay_t<T>, U>::type;

template <typename T>
std::enable_if_t<decays_to<T, Object>::value>
foo(T&& o) 
{
    // same stuff as before
}

但是第一个选项涉及编写两倍于我需要的函数,第二个选项涉及编写一堆模板内容,对我来说这似乎有些过分(我把它读为接受o的任何东西--哦,开玩笑,真的只是一个Object)。

是否有更好的方法来解决这个问题,还是我对其中任何一个感觉不太好?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-28 14:36:47

接受lvalue和rvalue的典型方法是创建一个接受const引用的函数。这意味着您不能在对象上调用非const函数,但是如果您想传递rvalue(比如临时的),那么调用非const函数就没有什么必要了。

票数 4
EN

Stack Overflow用户

发布于 2014-10-28 14:40:35

两种实现之间存在差异。第一个将承认任何可转换为ObjectObject&&Object&的东西。第二种只承认Object和以rvalue或lvalue形式继承的东西(并拒绝const Object,就像第一种)。

我们可以添加一个助手对象:

代码语言:javascript
复制
template<class T>
struct l_or_r_value {
  T& t;
  l_or_r_value( T&& t_ ):t(t_) {}
  l_or_r_value( T& t_ ):t(t_) {}
  operator T&(){ return t; }
  T* operator->(){ return &t; }
  T& operator*(){ return t; }
  T& get(){ return t; }
};

然后我们就可以写:

代码语言:javascript
复制
void foo(l_or_r_value<Object> o)

我们得到的行为非常接近于您的第二个解决方案,没有模板在呼叫点上的杂乱无章。您必须访问*oo->,或者执行Object& o = o_;才能获得原始引用。

它不像第一种解决方案,因为C++不链接两个用户定义的转换。

概念建议将增加“我在这里接受任何东西,只要它是Object”的能力,并提供更简洁的语法。

另一种方法是只使用Object&,并使用:

代码语言:javascript
复制
tepmlate<class T>
T& lvalue( T&& t) { return t; }

在需要时将rvalue转换为lvalue(您也可以称其为unmove,以使其可爱)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26610906

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档