C ++ - 如何通过引用返回prvalue?

时间:2014-12-03 19:43:26

标签: c++ c++11 rvalue

所以我实现了一个本机数组包装器,它允许将它作为函数参数传递并返回。我将其转换为本机数组时遇到了麻烦,因为无法返回本机数组。作为替代品,我决定使用' rvalue'引用返回类型的转换操作符,但这不会正确操作,因为如果我想将返回的对象绑定到一个“右值”中。参考是为了延长它的生命周期,这不会发生,因为它是一个' xvalue'而不是' prvalue'。这个问题有什么解决方案吗?也许一些' prvalue'投?或者,如果有其他方法可以实现这种隐式转换为'数组'?

班级:

template<typename type>
struct tmp
{
    tmp() {}
    tmp(const tmp &) = default;
    tmp(const type & arg) : tmp(*(const tmp*)arg) {}

    && operator type() && {return static_cast<type&&>(d);}

    ~tmp () { cout << "tmp destructor" << endl; }

    type d;

};

使用它的代码:

tmp<tmp<int [4]>> Func() // used 'tmp<int [4]>' instead of array to track object destruction (but normally it should be an native array type
{
    return tmp<tmp<int [4]>>();
}

int main()
{
    tmp<int [4]> &&tmp1 = Func(); //implicit cast (from 'tmp<tmp<int [4]>>') to 'tmp<int [4]>', calls tmp::operator type()

    cout << "Here" << endl;

    return 0;
}

节目输出:

  

tmp析构函数

     

tmp析构函数

     

下面

如您所见,不会延长演员操作符的返回值。

生命example

1 个答案:

答案 0 :(得分:2)

prvalue是一个不是xvalue的rvalue,也就是&#34;它的临时对象或子对象,或者与对象无关的值。&#34;

您无法创建a temporary object (12.2)的数组,也无法创建数组值that is not associated with an object.

要使数组成为prvalue,会留下subobject thereof个临时对象。

所以tmp

template<typename type>
struct tmp
{
  tmp() {}
  tmp(const tmp &) = default;
  tmp(tmp &&) = default;
  tmp(const tmp &&o):tmp(o) {}
  tmp(tmp &o):tmp(const_cast<tmp const&>(o)){}

  template<class... Ts>
  tmp(Ts&&...ts) : v{std::forward<Ts>(ts)...} {}

  ~tmp () { std::cout << "tmp destructor\n"; }

  type v;
};

A wrap_as_tmp

template<class X, class... Ts>
tmp<X> wrap_as_tmp(Ts&&... ts)
{
  return {std::forward<Ts>(ts)...};
}

跟踪我们使用noisy的破坏:

struct noisy {
  ~noisy() { std::cout << "bang\n"; }
};

然后测试:

int main() {
  auto&& x = wrap_as_tmp<noisy[4]>().v;
  std::cout << "There\n";
}

并注意There对象爆炸前的noisy输出。

live example

请注意在函数调用结束时使用.v

如果你的目标是避免这种情况,那就太糟糕了,你不能。