查找迭代器的值类型



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

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

这不起作用,我需要传递inititer的值类型,而不是整个迭代器。这个例子确实可以在下面工作,但显然我不能只留下std::size_t类型,否则我将被迫只创建std::size_t容器。

for_each_n(param1, param2, param3,
    [val](std::size_t& v){
        v = val;
    });

怎么做?

要获得迭代器的值类型,您应该从<iterator>使用std::iterator_traits,这将非常容易获得包装的value_type,并且足够泛型,以便您甚至可以与指针一起使用。

std::iterator_traits<InIter>::value_type
std::iterator_traits<char       *>::value_type                     => char
std::iterator_traits<char const *>::value_type                     => char const
std::iterator_traits<std::vector<int>::iterator      >::value_type => int
std::iterator_traits<std::vector<int>::const_iterator>::value_type => int const

如果你正在编写 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;
  }
);
for_each_n(param1, param2, param3, [val](decltype(*some_it) v){
  v = val;
});

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

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

最新更新