c++ - 前/后插入器就位

标签 c++ iterator c++14

在学习过程中,我遇到了前迭代器和后迭代器,我想知道是否有办法让它们就地创建容器元素。从文档来看,容器似乎需要实现push_back函数才能与back_iterator一起使用。但是有没有一种方法可以实现元素创建呢?

最佳答案

您所问的问题在概念上是不可能的。

迭代器作为一个概念表示某个对象的抽象,该对象引用一系列该类型的元素中的某种类型的元素。因此,basic Iterator concept具有取消引用迭代器的能力作为核心功能。也就是说 *it 是一个合法的表达式(虽然基本的 Iterator 并没有说明它的返回值是什么)。

back_insert_iterator通过...不实现它来实现*itOutputIterator concept允许*it,但它的结果是未指定的,所以你不能真正直接使用它。相反,您应该在像 *it++ = value; 这样的表达式中使用它。实际上调用 push_back 的是 operator= 重载。

这模仿了指针等自然迭代器的行为。它允许 OutputIterator 假装允许您分配给现有值,而您实际上是使用 operator= 调用 container.push_back*++ 只是为了匹配 ForwardIterators 的接口(interface)。

但是 operator= 是一个运算符。它是一个只接受两个参数的函数:迭代器(左侧)和分配给它的值。

emplace 类函数通过使用任意参数序列调用构造函数来工作。无法通过 operator= 来做到这一点。由于 OutputIterator 的接口(interface)仅限于此,因此迭代器没有有效的方法来使用这样的就地构造。


请注意,技术上有一种方法可以做到这一点。您需要的是一种将多个值打包到一个值中的方法:

auto it = back_emplacer(...);
*it++ = std::forward_as_tuple(...);

operator= 看起来像这样:

template<typename ...Args>
back_emplace_iterator &operator=(std::tuple<Args...> &&args)
{
  std::apply(
    [container](auto ...&&args)
      {container->emplace_back(std::forward<decltype(args)>(args)...);},
    std::forward<std::tuple<Args>>(args));
  return *this;
}

当然,缺点是您必须手动将数据打包到转发元组中。

关于c++ - 前/后插入器就位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48273319/

相关文章:

c++ - 我正在开始我的 C++ 学习,使用 CodeBlocks 和 Windows,我应该使用什么编译器?

c++ - C++中纯虚函数的实现

c++ - 在 C++ 中从在线文本文件中读取数据

c++ - 使用 shared_ptr 列表撤消/重做

c++ - forloop、迭代器和 vector 不配合我

c++ - 包括 std::forward 会产生错误,但它的遗漏会编译。为什么?

nvcc 不支持 C++11 函数 iota()?

C++:访问祖 parent 方法

c++ - 为什么模板参数中的 enable_if_t 提示重新定义?

c++ - 'iterator' 可以只输入子类 'const_iterator' 吗?