为什么std :: as_const(T& v)不能移动返回其参数? [英] Why can't std::as_const(T &&v) move-return its argument?

查看:72
本文介绍了为什么std :: as_const(T& v)不能移动返回其参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读为什么as_const禁止rvalue参数?我知道当然,我们不能将右值引用转换为左值引用.

Reading Why does as_const forbid rvalue arguments? I understand that we can't convert a rvalue-ref into an lvalue-ref, of course.

但是为什么不将rvalue-ref移到一个值中并返回它,即?

But why not move the rvalue-ref into a value and return that, i.e. ?

template<typename T> 
const T as_const(T&& val) { return std::move(val); } 

这也应该与COW容器一起很好地工作,因为返回的值是const,并且迭代器不会导致其分离.

This ought to work nicely with COW containers as well, as the returned value is const and iterators from it will not cause it to detach.

虽然也许有些固然可以回答这个问题,但是我想不出给定的方案,并且在AFAIK中没有容易获得的COW容器.

Maybe some godbolt-ing will answer this though, but I can't think of a given scenario and there are no COW containers easily available there AFAIK.

更新:

考虑此COW容器(忽略线程问题):

Consider this COW container (ignoring threading issues):

class mything {
   std::shared_ptr<std::vector<int>> _contents;

   auto begin() { if (_contents.use_count() > 1) { detach(); }
                  return _contents->begin(); }
   auto begin() const { return _contents->begin(); }
   void detach() {
       _contents = std::make_shared<decltype(_contents)>(*_contents); 
   }
   ...
};

在循环范围内使用时,移动会很快,并且返回的const T将选择begin()的const版本.

Move would be fast and the const T returned would select the const-version of begin() when used in range-for-loop.

也有一些容器将自己标记为已修改,因此它们的更改可以通过网络发送,或者以后同步到另一个副本(供在另一个线程中使用)f.ex.在OpenSG中.

There are also containers that mark themselves as modified so their changes can be sent over network or later synced to another copy (for use in another thread), f.ex. in OpenSG.

推荐答案

我将其理解为一项附加功能,但要避免一些误用:为具有地址的对象获取const视图.

I understand it as an additional feature to have but to avoid some measuses: get a const view to something which has an address.

由于临时地址没有地址,因此也应该没有该地址的const视图.

And because a temporary does not have an address, there should also be no const view of it.

移动值而不只是添加const会改变其语义(我们已经有了 std :: move )

And moving the value rather than just adding const would change it's semantics ( we already have std::move)

如果as_const临时存在会延长其生命周期,那么如果不进行绑定,则会浪费空间,例如:

And if as_const to a temporary would extend it's lifetime on it's own, then it would waste space if not bound, for example:

{
   as_const(f()); // if the lifetime would be extended
...
 } // not bound, but space wasted

例如, as_const const 添加到而不是类型,这样可以节省一些键入例如 static_cast add_const 等.

For example as_const adds const to a value rather than to a type, so it's saving some typing like static_cast, add_const etc.

通常将const左值ref绑定到临时目录会延长临时生存期,例如:

Normaly binding a const lvalue ref to a temporary, would extend the temporary lifetime, for example:

int f() { return 3; }

{
   const auto& x = f();
    ... use x .. ok
}

但是这样的事情会以悬挂的引用结尾:

But something like this would end to a dangling reference:

{
   auto& x = as_const(f()); // one could wrongly think that temporary lifetime is extended, but it's not
    ... x dangles ..
}

这篇关于为什么std :: as_const(T&amp; v)不能移动返回其参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆