【问题标题】:Filtering specific iterators for template functions过滤模板函数的特定迭代器
【发布时间】:2012-06-19 08:07:41
【问题描述】:

我正在开发一组函数,这些函数利用具有打包和顺序内存存储(用于内存副本)的容器。它们具有大多数 STD 函数风格的函数签名,输入/输出迭代器指向元素并表示范围。例如,一个函数可能如下所示:

template< typename InputIterator, typename OutputIterator >
OutputIterator fooBar( InputIterator& first, InputIterator& last, 
                       OutputIterator& result );

我希望验证传递的迭代器是否合法,即打包和顺序。对于 STD 容器,这仅限于 std::vector 和 std::array。不幸的是,我不能依赖迭代器“类别”特征,因为随机访问特征并不意味着顺序存储。这方面的一个例子是 microsofts concurrent_vector 类,记录在这里 parallel containers

此外,我也不能接受向量和数组类中的所有迭代器,例如我需要拒绝反向迭代器,而 std::vector&lt;bool> 迭代器不适合,因为它使用了代理类.

我试图创建自己的特征类来区分和过滤具有我上面描述的约束的迭代器,但我遇到了模板语法问题。我正在寻找其他人关于他们如何解决这个问题的反馈。

谢谢

【问题讨论】:

  • 您还需要注意value_type。只有 POD 可以是 memcpy'd。通常,大多数标准库已经尝试将std::copy 优化为memmove,您为什么不直接使用它呢?
  • 这个库的性质是给定 POD 的。它带有域。如果有人感兴趣,我可以详细说明,但我尽量笼统地陈述我的问题。

标签: c++ templates iterator


【解决方案1】:

我认为你做不到。迭代器是一种抽象,其全部目的是使迭代过程独立于底层架构。标准迭代器中没有任何信息表示底层内存结构甚至任何类似的东西。

在您的类似标准算法的函数中,通常建议按值传递迭代器,因为它们应该是廉价/小对象。应该特别注意的是,您的函数永远不能被称为fooBar(c.begin(), c.end(), some_out_it);,因为它通过引用非常量来获取输入迭代器。

最后一点,您可以通过测试迭代器类型是否是 std::reverse_iterator&lt;Iter&gt; 的特化来过滤掉反向迭代器,因为标准容器的至少 Container::(const_)reverse_iterator 类型必须是一个。

【讨论】:

  • 感谢您的回答。我正在研究的方法涉及创建一个“新”特征类,因此我想将自己的信息添加到迭代器中。与现在的 iterator_traits 类的工作方式非常相似,我只需要确保为我关心的迭代器定义了 iterator_traits SGI iterator 此外,这允许用户创建自己的迭代器并添加自己的特征元数据。你能告诉我关于迭代器传递值的文档吗?我对此并不熟悉。另外,为什么输入迭代器必须是 const?
  • @Kent:我认为您需要深入了解 C++ 中的参数传递是如何工作的。例如,void foo1(int); 按值获取 intvoid foo2(int&amp;); 通过引用获取int,并且引用为非const。现在,假设您有一个函数int bar();,它按值返回一个int(这是一个临时值)。您不能调用 foo2(bar()),因为临时对象不能绑定到非 const 引用。希望这有助于更好地理解这个问题。
  • 感谢您的提示。事实证明,Microsoft 编译器接受对非 const microsoft binding 的引用,但这不是符合标准的行为。
  • @Kent:没错,MSVC 在这方面太宽容了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
相关资源
最近更新 更多