我在我的一个重载函数中有一个模板参数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
来引用迭代器的值类型。由于模板专门化,这对自定义迭代器和指针都有效。因此,如果InIter
为T*
或const T*
为某些T
,您将获得正确的值类型。
自定义迭代器直接定义value_type
成员类型,但是在编写可以处理任何类型的迭代器的代码时,使用InIter::value_type
引用迭代器的值类型是不安全的,因为InIter
可能只是一个指针,没有value_type
成员类型。