Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么std::as_const(t&&v)move不能返回其参数?_C++_C++17_Rvalue Reference - Fatal编程技术网

C++ 为什么std::as_const(t&&v)move不能返回其参数?

C++ 为什么std::as_const(t&&v)move不能返回其参数?,c++,c++17,rvalue-reference,C++,C++17,Rvalue Reference,阅读本文,我明白我们当然不能将右值ref转换为左值ref 但是为什么不将右值ref移动到一个值中并返回该值,即 template<typename T> const T as_const(T&& val) { return std::move(val); } 这应该可以很好地处理COW容器,因为返回的值是const,来自它的迭代器不会导致它分离 也许一些godbolt-ing会回答这个问题,但我想不出一个给定的场景,那里没有容易获得的奶牛容器 更新: 考虑以下问

阅读本文,我明白我们当然不能将右值ref转换为左值ref

但是为什么不将右值ref移动到一个值中并返回该值,即

template<typename T> 
const T as_const(T&& val) { return std::move(val); } 
这应该可以很好地处理COW容器,因为返回的值是const,来自它的迭代器不会导致它分离

也许一些godbolt-ing会回答这个问题,但我想不出一个给定的场景,那里没有容易获得的奶牛容器

更新:

考虑以下问题:

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); 
   }
   ...
};
移动速度会很快,返回的常量T将在循环范围内使用时选择begin的常量版本


还有一些容器将自己标记为已修改,这样它们的更改可以通过网络发送,或者稍后同步到另一个副本,以便在另一个线程f.ex中使用。在OpenSG中。

我认为这是一个额外的功能,但要避免一些措施:获取一个有地址的东西的常量视图

而且因为临时文件没有地址,所以也不应该有它的const视图

移动值而不是仅仅添加常量会改变它的语义,我们已经有了std::move

如果as_const to a temporary会单独延长它的生命周期,那么如果不绑定它就会浪费空间,例如:

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

{
   const auto& x = f();
    ... use x .. ok
}
例如,由于_const将const添加到值而不是类型,因此它可以保存一些类型,如static_cast、add_const等

将常量左值ref正常绑定到临时变量将延长临时生命周期,例如:

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

{
   const auto& x = f();
    ... use x .. ok
}
但类似这样的事情最终会成为一个悬而未决的参考:

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

我的猜测很简单,这不是函数的用途:它的意思是“将此非常量引用转换为常量引用”,不是“确保我在所有情况下都得到常量”。返回值非引用上的常量基本上是meaningless@Caleth不适用于其非常量begin/end函数创建新副本(也称为detach)的写时复制容器,因为它们预期内容会更改。在任何情况下,将std::moveval返回为T都将生成val的副本。此外,返回std::move。。。是一种通常禁止NRVO的反模式。但是,即使NRVO在返回输入参数时也没有帮助,始终会涉及到复制。好的,如果我们忽略非类常量t的问题,您的版本仍然会返回一个新的t实例。如果左值引用重载返回对同一对象的引用,这将产生误导,而右值引用是一个新对象。这就是为什么我建议从r值引用返回值,而不是从左值引用返回值,因为我们不能从函数返回r值引用。@Macke-当然可以。这就是std::move的工作原理。@StoryTeller UnslanderMonica所以我需要的是std::move_to_const?:。。我的问题是什么?我能做到顺便说一句,r值参考的整个点不是你可以移动到一个位置或类似的位置。因此,将其移动到我们返回的值并不坏。。它就像从一个变量中移出某个变量并返回它。我认为r值是一种标志,表明它是可移动的。但如果一个人真的离开了它,我想这是另一回事了。