查找迭代器的值类型

Syn*_*ose 1 c++ lambda iterator c++11

InIter在我的一个重载函数中有一个模板参数,我需要调用一个for for_each_n循环来InIter进行x迭代,我没有遇到任何麻烦.但是我在获取迭代器的值类型时遇到了麻烦,举个例子:

//invalid lambda function
for_each_n(param1, param2, param3,
    [val](InIter it) {
        *it = val;
    });
Run Code Online (Sandbox Code Playgroud)

但这不起作用,我需要传入InIter的值类型而不是整个迭代器.这个例子在下面工作,但显然我不能只留下类型std::size_t或我将被迫只创建std::size_t容器.

for_each_n(param1, param2, param3,
    [val](std::size_t& v){
        v = val;
    });
Run Code Online (Sandbox Code Playgroud)

Fil*_*efp 6

怎么做..

要获取价值型,你应该使用迭代器的std::iterator_traits距离<iterator>,这将使其很容易获得的包裹VALUE_TYPE,以及作为一般足以让你甚至可以用它的指针.

std::iterator_traits<InIter>::value_type
Run Code Online (Sandbox Code Playgroud)
std::iterator_traits<char       *>::value_type                     => char
std::iterator_traits<char const *>::value_type                     => char const
Run Code Online (Sandbox Code Playgroud)
std::iterator_traits<std::vector<int>::iterator      >::value_type => int
std::iterator_traits<std::vector<int>::const_iterator>::value_type => int const
Run Code Online (Sandbox Code Playgroud)

替代

如果您正在编写C++ 11,并且有一个实例InIter,那么也可以使用它 decltype来获取类型*it,有效地(在大多数情况下/所有情况下)与std::iterator_traits<T>::value产生的类型相同.


履行

从您的示例代码段来看,似乎您不是想要迭代器的value_type,而是对实际的引用类型更感兴趣,下面是一个示例实现:

for_each_n(param1, param2, param3,
  [val](typename std::iterator_traits<InIter>::reference v){
    v = val;
  }
);
Run Code Online (Sandbox Code Playgroud)
for_each_n(param1, param2, param3, [val](decltype(*some_it) v){
  v = val;
});
Run Code Online (Sandbox Code Playgroud)


Tim*_*lds 5

使用std::iterator_traits.您可以使用它std::iterator_traits<InIter>::value_type来引用迭代器的值类型.由于模板特化,这将适用于自定义迭代器和指针.因此,如果InIterT*const T*某些T,您将获得正确的值类型.

自定义迭代器value_type直接定义成员类型,但是在编写可以处理任何类型的迭代器的代码时,使用它InIter::value_type来引用迭代器的值类型是不安全的,因为它InIter可能只是一个没有value_type成员类型的指针.

  • +1,但不鼓励直接访问`iterator :: value_type`(如果没有信息).强调`iterator_traits`方法. (2认同)