反转元组并反转列表会返回不同类型的对象:
>>> reversed((1,2))
<reversed at 0x7fffe802f748>
>>> reversed([1,2])
<list_reverseiterator at 0x7fffebdd4400>
Run Code Online (Sandbox Code Playgroud)
他们也一样dir.这两种类型都不是另一种类型的子类.
这是为什么?一个人可以做什么,另一个不能?
有没有办法检查迭代器是否作为arg传递给fnc是reverse_iterator?我可以使用任何迭代器特征函数吗?
我知道如何从向量迭代器中获取索引,方法是从中减去begin迭代器.例如:
vector<int>::iterator it = find(vec.begin(), vec.end(), x);
size_t position = it - vec.begin();
Run Code Online (Sandbox Code Playgroud)
但是,现在我想找到x向量中最后一个的索引.如何从反向迭代器中获取实际索引?我发现以下似乎有效(编辑:它没有)但也许有更好的(更惯用或其他......)方式.
vector<int>::reverse_iterator it = find(vec.rbegin(), vec.rend(), x);
size_t position = vec.size() - (it - vec.rbegin());
Run Code Online (Sandbox Code Playgroud) 使用XCode 4.6在Mac OS X上测试.
此示例代码显示std::list正如我所期望的那样删除工作的最后一个元素:迭代器引用list::end()仍然是"1结束"并且仍然有效,即使删除了最后一个元素.
但第二个例子反驳了我的直觉.删除列表的第一个元素会发生变化list::rend(),我认为这是"从头开始".
我的期望是错的吗?为什么这是错的?为什么通过删除最后一个元素引用"1结束"仍然有效(如果不是?),但.rend()删除前元素后对"1(在开头()前面"的引用变为无效?
void printList( list<int>& os )
{
for( int& i : os )
printf( "%d ", i ) ;
puts("");
}
void testList()
{
list< int > os ;
os.push_back( 1 ) ;
os.push_back( 2 ) ;
os.push_back( 3 ) ;
os.push_back( 4 ) ;
os.push_back( 5 ) ;
// Forward iterators: reference to .end() not invalidated when remove last elt. …Run Code Online (Sandbox Code Playgroud) 要使用POD元素搜索C-Array中元素的第一个出现,可以轻松实现std::find_if(begin, end, findit).但我需要最后一次出现.这个答案让我觉得这可以做到std::reverse_iterator.因此,我试过:
std::find_if(std::reverse_iterator<podtype*>(end),
std::reverse_iterator<podtype*>(begin),
findit);
Run Code Online (Sandbox Code Playgroud)
这给了我错误:
无法在赋值时将'std :: reverse_iterator <xyz*>'转换为'xyz*'
您是否知道如何以这种方式进行操作或者您是否知道更好的解决方案?
这是代码:
#include <iostream>
#include <iterator>
#include <algorithm>
struct xyz {
int a;
int b;
};
bool findit(const xyz& a) {
return (a.a == 2 && a.b == 3);
}
int main() {
xyz begin[] = { {1, 2}, {2, 3}, {2, 3}, {3, 5} };
xyz* end = begin + 4;
// Forward find
xyz* found = std::find_if(begin, end, findit);
if (found …Run Code Online (Sandbox Code Playgroud) 我想知道使用rbegin()而不是end() - 1对STL容器有什么好处.
例如,为什么你会使用类似的东西:
vector<int> v;
v.push_back(999);
vector<int>::reverse_iterator r = v.rbegin();
vector<int>::iterator i = r.base();
Run Code Online (Sandbox Code Playgroud)
而不是:
vector<int> v;
v.push_back(999);
auto r = v.end() - 1;
Run Code Online (Sandbox Code Playgroud) 我有一个二维数组。按正向迭代行是完全可以的,但是当我反向执行时,它不起作用。我不明白为什么。
我正在使用 MSVC v143 和 C++20 标准。
int arr[3][4];
for (int counter = 0, i = 0; i != 3; ++i) {
for (int j = 0; j != 4; ++j) {
arr[i][j] = counter++;
}
}
std::for_each(std::begin(arr), std::end(arr), [](auto const& row) {
for (auto const& i: row) {
fmt::print("{} ", i);
}
fmt::print("\n");
});
std::for_each(std::rbegin(arr), std::rend(arr), [](auto const& row) {
for (auto const& i: row) {
fmt::print("{} ", i);
}
fmt::print("\n");
});
Run Code Online (Sandbox Code Playgroud)
第一个的输出for_each很好:
0 1 2 3 …Run Code Online (Sandbox Code Playgroud) 似乎迭代器适配器reverse_iterator双重定义了大多数嵌套类型.特别是,从公开继承std::iterator暴露iterator_category,value_type,difference_type,pointer和reference.除了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_category和value_type?
c++ iterator language-lawyer iterator-traits reverse-iterator
我想std::vector在for循环中迭代一些s,但是根据某些条件,向量应该向前或向后迭代.我想,我可以通过使用普通迭代器或反向迭代器来轻松实现,如下所示:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec{0, 1, 2, 3, 5, 6, 7};
bool reverse = true;
std::iterator<random_access_iterator_tag, int> it, end_it;
if (reverse) {
it = vec.rbegin();
end_it = vec.rend();
} else {
it = vec.begin();
end_it = vec.end();
}
for (; it != end_it; it++) {
cout << *it << ", ";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但不幸的是vector::begin(),vector::rbegin()似乎并没有使用相同的父类.是否有另一种方法可以做我想要的,而不在if-else结构中有两个不同的循环?当然我可以为循环体创建一个函数/ lambda或者使用一些索引算法但是有更优雅的方法吗?
编译器抱怨分配,it = vec.begin()因为它们是不同的类型.gcc和VC++输出不同的错误,似乎使用不同的类型作为返回值vector::begin.
我正在尝试解决 C++ 中的一个问题,其中一部分要求我使用rbegin()成员函数从向量中删除元素。但是,每次我编写下面提到的代码时,编译器都会抛出错误。这里有什么问题?
int main() {
int a = 1, b = 2;
vector<int> V = {a, b};
auto it = V.rbegin();
V.erase(it);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用begin()成员函数访问相同的元素,它编译得很好。下面的代码工作正常。
int main() {
int a = 1, b = 2;
vector<int> V = {a, b};
auto it = V.begin()+1;
V.erase(it);
return 0;
}
Run Code Online (Sandbox Code Playgroud)