标签: iterator-traits

连续迭代器检测

C++ 17引入了ContiguousIterator的概念http://en.cppreference.com/w/cpp/iterator.然而,似乎没有计划contiguous_iterator_tag(通过我们现在以同样的方式random_access_iterator_tag)报告std::iterator_traits<It>::iterator_category.

为什么contiguous_iterator_tag失踪?

是否有传统的协议来确定迭代器是否是连续的?还是编译时间测试?

在过去我提到过,对于容器,如果有一个.data()成员转换为指向::value类型的指针,并且有.size()成员可转换为指针差异,那么应该假设容器是连续的,但我不能提取迭代器的类似特征.

一种解决方案可能是data为连续迭代器提供一个函数.

当然,连续概念&(it[n]) == (&(*it)) + n在所有情况下都有效n,但在编译时无法检查.


编辑:我发现这个视频把它放在更广泛的C++概念上下文中.CppCon 2016:"在现代多核世界中构建和扩展迭代器层次结构",作者:Patrick Niedzielski.解决方案使用概念(Lite),但最后的想法是连续的迭代器应该实现一个pointer_from函数(与我的data(...)函数相同).

结论是概念将有助于形式化理论,但它们并不神奇,在某种意义上,某个人会在某个地方定义新的特别命名的函数而不是连续的迭代器.这个讨论概括了分段迭代器(带有相应的函数segmentlocal),不幸的是它没有说明跨步指针.

c++ iterator iterator-traits c++17

27
推荐指数
1
解决办法
1826
查看次数

iterator_trait的典型用例是什么?

我是C++的新手,所以请耐心等待.我想了解STL iterator_traits.在"C++标准库"一书中,iterator_traits结构定义如下:

template <class T>
struct iterator_traits{
  typedef typename T::value_type value_type
  typedef typename T::difference_type difference_type
  typedef typename T::iterator_category iterator_category
  typedef typename T::pointer pointer
  typedef typename T::reference reference
}
Run Code Online (Sandbox Code Playgroud)

所以在我看来,它正在重新暴露T已经暴露的子类型.继续前进,本书给出了如何使用它的示例,如下所示

template <class MyIterator>
void do_something(MyIterator start, MyIterator end) {
    typedef typename iterator_traits<MyIterator>::value_type value_type
    value_type v = *start
    .....
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么我在这里需要这个iterator_traits结构,如果想要获得它value_type,我不能MyIterator直接获得它吗?我的困惑似乎来自于我(肯定是不正确的)理解,即子类型的信息必须来源于template <class T>用于实例化iterator_trait.所以如果你能解释一下,最好用一个例子说明为什么以及在哪里我需要iterator_traits,这将是非常有帮助的.

c++ iterator stl traits iterator-traits

21
推荐指数
1
解决办法
4351
查看次数

为什么back_insert_iterator/front_insert_iterator/insert_iterator的value_type/difference_type/pointer/reference都是无效的?

在我的项目中,我想将流分割为某些给定类型的值,因此我将模板函数实现为

template <typename TElem, typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    TElem elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

我认为这很尴尬,因为我必须明确给出TElem调用时的类型.例如,我必须写:

std::vector<int> v;
SplitSpace<int>(std::cin, back_inserter(v));
// I want to it to be   SplitSpace(std::cin, back_inserter(v)); 
Run Code Online (Sandbox Code Playgroud)

我试图从(模板)迭代器获取值类型并使用std::iterator_traits如下:

template <typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    typename std::iterator_traits<TOutputIter>::value_type elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

但是,上述代码不起作用back_insert_iterator.我检查的源代码back_insert_iterator/front_insert_iterator/insert_iteratorstd的命名空间,发现value_type/difference_type/pointer/reference都是 …

c++ types iterator iterator-traits

19
推荐指数
2
解决办法
850
查看次数

const_iterator和const_iterator :: value_type的constness

为何选择STL

std::iterator_traits<const T*>::value_type
Run Code Online (Sandbox Code Playgroud)

与...的类型相同

std::iterator_traits<T*>::value_type
Run Code Online (Sandbox Code Playgroud)

为什么它的设计是这样的?首先不应该是const T而第二个是T吗?你应该如何采用底层const正确类型的迭代器?我知道你可以编写自己的模板类和专业化并从中获取

    std::iterator_traits<const T*>::pointer
Run Code Online (Sandbox Code Playgroud)

但不应该有一个成员typedef持有它吗?

c++ iterator const-iterator iterator-traits

14
推荐指数
2
解决办法
1613
查看次数

为什么我不能从iterator_traits获取value_type?

我这样做:

const int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;
Run Code Online (Sandbox Code Playgroud)

我本来期望bar有这种类型int.但相反,我得到一个错误:

错误C2039 :: value_type不是.的成员std::iterator_traits<_Ty *const >

这是const我需要剥离那个什么的问题吗?

c++ types iterator typename iterator-traits

13
推荐指数
2
解决办法
647
查看次数

为什么算法使用 iterator_traits&lt;T&gt;::value_type 而不是 iter::value_type?

在算法中,我可以value_type通过 直接从迭代器确定iter::value_type。为什么算法会iterator_traits做同样的事情?

#include <iostream>
#include <vector>
#include <iterator>
#include <typeinfo>
using namespace std;

template<typename iter>
void for_each(iter first, iter end)
{
    cout << "container value type: "
         << typeid(typename iter::value_type).name()
         << endl;

    cout << "container value type: "
         << typeid(typename iterator_traits<iter>::value_type).name()
         << endl; 
}

int main()
{
    vector<int> v1;
    for_each(begin(v1), end(v1));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

container value type: i
container value type: i
Run Code Online (Sandbox Code Playgroud)

c++ templates iterator iterator-traits

11
推荐指数
2
解决办法
1049
查看次数

前向迭代器是输出迭代器吗?

ForwardIterators是否必须是OutputIterators?我现在的STL的实现(VS2012)派生forward_iterator_tag从两个input_iterator_tagoutput_iterator_tag,但我找不到标准[N3485]这个要求.

c++ iterator-traits

10
推荐指数
1
解决办法
414
查看次数

为什么reverse_iterator会双重定义其嵌套类型?

似乎迭代器适配器reverse_iterator双重定义了大多数嵌套类型.特别是,从公开继承std::iterator暴露iterator_category,value_type,difference_type,pointerreference.除了iterator_category和之外value_type,这些都typedef在类定义中再次明确地使用.

24.5.1.1类模板reverse_iterator [reverse.iterator]

namespace std {
template <class Iterator>
class reverse_iterator : public
     iterator<typename iterator_traits<Iterator>::iterator_category,
     typename iterator_traits<Iterator>::value_type,
     typename iterator_traits<Iterator>::difference_type,
     typename iterator_traits<Iterator>::pointer,
     typename iterator_traits<Iterator>::reference> {
public:
  typedef Iterator                                            iterator_type;
  typedef typename iterator_traits<Iterator>::difference_type difference_type;
  typedef typename iterator_traits<Iterator>::reference       reference;
  typedef typename iterator_traits<Iterator>::pointer         pointer;
  // ... rest of the class
};
Run Code Online (Sandbox Code Playgroud)

问题:为什么重复定义?这只是为了说明的目的,还是有更多的东西?为什么不重新定义iterator_categoryvalue_type

c++ iterator language-lawyer iterator-traits reverse-iterator

9
推荐指数
1
解决办法
217
查看次数

专门化iterator_traits

我想专门std::iterator_traits<>为一个容器类模板的迭代器,它具有通常的嵌套类型定义(如value_type,difference_type等),其源我不应该修改.基本上我想做这样的事情:

template <typename T> struct iterator_traits<typename Container<T>::iterator> 
{
    typedef T value_type; 
    //  etc.
}; 
Run Code Online (Sandbox Code Playgroud)

除了这不起作用,因为编译器无法推断TContainer<T>::iterator.

是否有任何工作方式来实现相同的目标?


例如:

template <typename T>
class SomeContainerFromAThirdPartyLib
{
    typedef T ValueType;    //  not value_type! 
    //  no difference_type

    class iterator
    {
        typedef T ValueType;    //  not value_type! 
        //  no difference_type  
        ...
    }; 
    iterator begin() { ... }
    iterator end() { ... }
    ...
}; 
Run Code Online (Sandbox Code Playgroud)

现在假设我std::count()使用此类的实例调用.据我所知,在大多数STL实现中,count()返回iterator_traits<Iterator>::difference_type.iterator_traits<I>简单的主要模板typedef …

c++ template-specialization iterator-traits

8
推荐指数
2
解决办法
5734
查看次数

规范正向输出迭代器的规范方法

如何以规范的方式在C++ 11中定义forward-output-iterators?

根据标准,forward_iterator只是一个input_iterator.所以相应的forward_iterator_tag只是延伸input_iterator_tag.如果我们std::iterator用来定义迭代器,我们使用什么标签作为正向输出迭代器?

定义扩展两者的私有标记是否规范forward_iterator_tag,output_iterator_tag或者是否有更好的解决方案?

c++ iterator-traits c++11

7
推荐指数
1
解决办法
509
查看次数