STL容器的右值引用限定符

6
为什么STL容器的元素访问成员函数(例如std::array::operator[]或std::vector::operator[])没有rvalue ref-qualifier重载?当然我可以使用std::move(generate_vector()[10]),但我很好奇在标准化ref-qualifiers时是否考虑添加rvalue ref-qualifier重载。
我认为std::array和std::tuple实际上是相同的东西,后者的“元素访问函数(即std::get)”针对const vs non-const和lvalue vs rvalue的所有组合都进行了重载。为什么前者没有?
向我的自定义容器添加返回rvalue引用的rvalue ref-qualified元素访问成员函数是否是个好主意?
编辑
对于Richard Critten的评论。我认为这可能偶尔会有用。
例如,您有一个在函数内构造的容器并返回该容器的函数,但您可能只对该容器的第一个元素感兴趣。是的,这很傻。在这种情况下,肯定最好使用仅构造第一个元素的简单函数。但是如果该函数不是您的,您就没有这样的选择。
或者,可能会有更一般的例子。您有一个构造容器的函数,并希望处理该容器以获得另一个结果。 例如,您可能希望对该容器执行std::reduce或std::unique_copy。(似乎在执行std::reduce期间禁止修改元素,但是让我们假设我们已经实现了允许修改的自己的函数。)在这种情况下,可以使用std::make_move_iterator,但为什么不让容器本身返回移动迭代器呢?
编辑2
事实上,当我正在为容器类实现一些“视图”类时,我遇到了这个问题。需要可变视图(lvalue引用)、不可变视图(const引用)和可移动视图(rvalue引用),我必须确定可移动视图类的元素访问成员函数应该返回lvalue还是rvalue引用?对我来说,将rvalue引用返回给容器本身不公开此类接口的元素感觉有点奇怪。哪一个是正确的?
1. lvalue引用。 2. rvalue引用。 3. 通常来说,可移动视图并不正确。这样的东西不应该经常需要,并且我的设计中应该存在一些严重的问题。

返回一个即将被销毁的容器的引用,似乎并不那么有用。您能否扩展一下问题,以显示如何使用它? - Richard Critten
std::get(std::array)&&&重载,它没有T重载,因为那不能区分元素。 - Caleth
@Caleth,你说的“T”重载是什么意思? - Junekey Jeon
你可以使用std::get<bool>获取std::tuple<int, char, bool>的值,但对于std::array<bool, 10>则没有意义。C++17增加了第四个版本的const &&,适用于std::get (std::array)std::get (std::tuple)两者。 - Caleth
@Caleth 啊哈。但是这和这个问题有什么关联吗? - Junekey Jeon
1个回答

1

在所有返回引用的内容中添加ref-qualifier并没有什么特别的问题,但这基本上会使成员数量翻倍,尽管它们通常除了将返回值包装在std::move中之外,具有相同的实现。

class A
{
    int a;

    int& operator[](std::size_t pos) & { return a; }
    int&& operator[](std::size_t pos) && { return std::move(a); }
};

标准库拒绝提供这些重载,就像它拒绝提供许多volatile重载一样。在这种情况下,您可以在需要时只是使用std::move&值。
如果您正在编写自己的容器,则没有避免使用此类重载的安全性原因。但会增加维护负担,因此我建议不要使用。

非常感谢。你能进一步评论我的第二次编辑吗? - Junekey Jeon
“可移动视图”是不是类似于 someFunction(filter(make_collection())) 这样的东西?在 someFunction 中,您希望能够从 filter_view 暴露的元素中移动? - Caleth
我认为你是正确的。我认为someFunction可以被看作是类似于std::unique的东西。 - Junekey Jeon
这听起来像是一个专门化的模板 template <class Container> class view<Container&&> { .. },带有移动方法。 - Caleth
如果可能的话最好避免使用“可移动视图”,或者不要将此类东西视为容器的“右值引用代理”,因为没有办法构建一个正确行为类似于右值引用的类。类型为“T&&”的表达式“x”实际上是类型为“T&”,但是从“T&&”到“T&”没有转换。这种奇特的行为无法使用“可变视图”和“可移动视图”来模仿......也许不提供右值引用限定重载并不仅仅是维护负担的原因。 - Junekey Jeon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接