简体   繁体   English

STL容器的右值ref限定词

[英]rvalue ref-qualifiers for STL containers

Why element access member functions of STL containers, eg std::array::operator[] or std::vector::operator[] do not have rvalue ref-qualifier overloads? 为什么STL容器的元素访问成员函数(例如std::array::operator[]std::vector::operator[]没有右值引用限定符重载? Of course I can do std::move(generate_vector()[10]) , but I'm curious if adding rvalue ref-qualifier overloads was considered when ref-qualifiers were being standardized. 当然我可以做std::move(generate_vector()[10]) ,但是我很好奇在标准化ref限定符时是否考虑添加右值ref限定符重载。

I think std::array<T, N> and std::tuple<T, T, ..., T> are really the same thing, and the "element access function (ie, std::get )" of the latter is overloaded for all combinations of const vs non-const and lvalue vs rvalue. 我认为std::array<T, N>std::tuple<T, T, ..., T>确实是同一回事,并且该对象的“元素访问函数(即std::get )”对于const vs non-const以及lvalue vs rvalue的所有组合,后者都是重载的。 Why not the former? 为什么不选择前者?

Is it a good idea to add rvalue ref-qualified element access member functions (which return rvalue references) to my custom container? 将rvalue ref限定的元素访问成员函数(返回rvalue引用)添加到我的自定义容器中是一个好主意吗?

EDIT 编辑

To Richard Critten's comment. 理查德·克里滕(Richard Critten)的评论。 I think this can be occasionally useful. 我认为这有时会有用。

For example, you have a function that returns a container constructed inside that function, but you may be interested only to the first element of that container. 例如,您有一个函数返回在该函数内部构造的容器,但是您可能只对该容器的第一个元素感兴趣。 Yes, that's silly. 是的,这很愚蠢。 In that case, it's definitely better to use simpler function that only constructs the first element. 在这种情况下,最好使用只构造第一个元素的简单函数。 But if the function is not yours, you have no such a choice. 但是,如果该功能不是您的功能,那么您别无选择。

Or, there may be more general examples. 或者,可能会有更一般的示例。 You have a function that constructs a container, and you wish to process that container to get another result. 您有一个构造容器的函数,并且希望对该容器进行处理以获得另一个结果。 For example, you may wish to perform std::reduce , or std::unique_copy to that container. 例如,您可能希望对该容器执行std::reducestd::unique_copy (It seems that it is prevented to modify elements during performing std::reduce , but let us just assume we have implemented our own that allows modifications.) In this case, one may use std::make_move_iterator , but why not let the container itself returns move iterators? (似乎可以防止在执行std::reduce修改元素,但是让我们假设我们已经实现了允许修改的元素。)在这种情况下,可以使用std::make_move_iterator ,但是为什么不让容器本身返回移动迭代器?

EDIT2 编辑2

In fact I encountered this problem when I'm implementing some "view" classes to a container class. 实际上,当我在容器类中实现一些“视图”类时遇到了这个问题。 Mutable view (lvalue reference), immutable view (const reference), and movable view (rvalue reference) seem to be all needed, and I have to determine what to return from element access member functions of the movable view class: lvalue or rvalue references? 似乎都需要可变视图(左值引用),不可变视图(常量参考)和可移动视图(右值引用),我必须确定从可移动视图类的元素访问成员函数返回什么:左值或右值引用? It felt a little bit weird to me, to return rvalue references to elements where the container itself does not expose such interfaces. 将右值引用返回到容器本身未公开此类接口的元素,这让我感到有些奇怪。 Which one is correct? 哪一个是正确的?

  1. lvalue references. 左值引用。
  2. rvalue references. 右值引用。
  3. Movable view, in general, is not right. 通常,可移动的视图是不正确的。 Such thing should not be needed that often, and there should be some serious problems in my design. 不需要经常这样的事情,并且在我的设计中应该存在一些严重的问题。

There isn't a particular problem with adding ref-qualifiers to everything that returns references, however that basically doubles the number of members, which will generally have identical implementations apart from wrapping the return in std::move . 向返回引用的所有内容添加ref-qualifier并没有什么特别的问题,但是,这基本上使成员的数量增加了一倍,除了将return包装在std::move之外,通常具有相同的实现。

class A
{
    int a;

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

The standard library has declined to provide these overloads, in the same way that it has declined to provide many volatile overloads. 标准库拒绝提供这些重载,就像拒绝提供许多volatile重载一样。 In this case, you can just std::move the & value, where you need it. 在这种情况下,您可以只在需要的地方std::move &值。

If you are writing your own containers, then there is no safeness reason to avoid such overloads. 如果您正在编写自己的容器,则没有安全理由可以避免此类重载。 It does increase the maintenance burden , so I would advise against it. 它确实增加了维护负担 ,所以我建议不要这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM