C++ 为什么std::as_const(t&&v)move不能返回其参数?
阅读本文,我明白我们当然不能将右值ref转换为左值ref 但是为什么不将右值ref移动到一个值中并返回该值,即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会回答这个问题,但我想不出一个给定的场景,那里没有容易获得的奶牛容器 更新: 考虑以下问
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值是一种标志,表明它是可移动的。但如果一个人真的离开了它,我想这是另一回事了。