gpt4 book ai didi

c++11 - move 容器的迭代器?

转载 作者:行者123 更新时间:2023-12-04 03:56:15 25 4
gpt4 key购买 nike

C++98 容器定义了两种迭代器,::iterator s 和 ::const_iterators .一般来说,像这样:

struct vec{
iterator begin() ;
const_iterator begin() const;
};
在 C++11 中,这部分设计似乎没有改变。
问题是,
为了一致性和实际目的,添加 ::move_iterator 是否有意义?也一样? 或者它是一个矫枉过正。
我可以想象,如果可能的话,右值容器可能会 move 它们的元素。
class vec{
iterator begin() &;
const_iterator begin() const&;
move_iterator begin() &&;
};
如果我理解正确,可以在简单的情况下这样实现:
    auto vec::begin() &&{return std::make_move_iterator(this->begin());}

当然,普通迭代器可以转换为 move 迭代器(使用 std::make_move_iterator ),但是动机是通用代码。
例如,使用 move 迭代器,这将在没有条件的情况下非常优雅地实现,具体取决于参数是左值还是右值。
template<class Container, class T = Container::value_type>
void transport_first(Container&& c, std::vector<T>& v){
v.emplace_back(*std::forward<Container>(c).begin());
}
请注意,如果可能,此代码不会产生不必要的副本。
没有 move_iterators 怎么实现?由 begin 生成.

我也意识到这个问题几乎适用于容器的任何访问器,例如, operator[] , front()back() .
    template<class Value>
class vec{
using value_type = Value;
using reference = Value&;
using const_reference = Value const&;
using rvalue_reference = Value&&; // NEW!
reference front() &{...}
rvalue_reference front() &&{...} // NEW!
const_reference front() const&{...}
};
也许容器应该在 C++11 中从头开始重新设计。
他们的设计正在显示它的时代。

有一个提议,自动推导出 (*this) 的(decl)类型基本上免费拥有 begin (和其他成员函数)的所有相应重载。
https://youtu.be/yB4E-SzQPdI?t=4131

最佳答案

STL 容器旨在与 STL 算法结合使用。当前在 STL 中找到的通用算法处理迭代器,但您的模板函数 transport_first :

template<class Container, class T = Container::value_type>
void transport_first(Container&& c, std::vector<T>& v){
v.emplace_back(*std::forward<Container>(c).begin());
}

由基于容器的代码组成,即:它在容器而不是迭代器上运行。多亏了概念,我们也许能够在 C++20 的 STL 中找到这样的基于容器的算法。

通用 transport_first 算法的“类似 STL 的方法”实际上是:
template<typename InIt, typename OutIt>
void transport_first(InIt src, OutIt dst) {
*dst = *src;
}

遵循这种方法(即:迭代器而不是容器),当涉及到泛型代码时,是否使用 move_iterator 可以简单地在“最顶层”泛型算法处确定,因为传递的迭代器被进一步复制(即:被传递值到“基础”算法中)。

此外,与上面基于迭代器的 transport_first 不同,STL 充满了基于迭代器对的算法(例如: std::copy)来实现范围。这个接口(interface)使得在右值上重载那些容器成员函数没有什么吸引力,因为正如 this other answer 中已经说明的那样,这些重载的成员函数将在未命名(非 const )容器对象上被调用,并且未命名的容器对象仅限于使用在单个表达式中,通过在同一容器对象上调用 begin()end() 成员函数来阻碍迭代器对的创建。

对于容器来说真正有意义的是拥有新的成员函数来返回相应的 move_iterator 对象:
move_iterator Container<T>::mbegin();
move_iterator Container<T>::mend();

这只是调用 std::make_move_iterator 的快捷方式,成员函数返回的值返回 iterator 。成员函数 mbegin() 将在基于迭代器的 transport_first 中用作:
transport_first(coll.mbegin(), std::back_inserter(vec));

相应的函数模板 std::mbegin()std::mend() 也有意义:
transport_first(std::mbegin(coll), std::back_inserter(vec));

关于c++11 - move 容器的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48915905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com