我想提供两种迭代器:
第一个集合,即常规迭代器,可以指向任何元素,无论是设置还是未设置.如果它们被读取,它们将返回设置值,或者value_type(),如果它们被写入,则它们创建元素并返回左值引用.因此,它们是:
随机访问遍历迭代器和可读和可写迭代器
第二个集合,即稀疏迭代器,仅迭代set元素.由于他们不需要懒惰地创建写入的元素,因此它们是:
随机访问遍历迭代器和可读和可写和左值迭代器
我还需要两者的const版本,这些版本都是不可写的.
我可以填写空白,但不知道如何使用boost :: iterator_adaptor开始.
这是我到目前为止所拥有的:
template<typename T>
class sparse_vector {
public:
typedef size_t size_type;
typedef T value_type;
private:
typedef T& true_reference;
typedef const T* const_pointer;
typedef sparse_vector<T> self_type;
struct ElementType {
ElementType(size_type i, T const& t): index(i), value(t) {}
ElementType(size_type i, T&& t): index(i), value(t) {}
ElementType(size_type i): index(i) {}
ElementType(ElementType const&) = default;
size_type index; …Run Code Online (Sandbox Code Playgroud) 我一直在使用advance一些iterators,但恐怕上述可能的越级end().我想确保我的迭代器保持在界限之间,我想到了distance但似乎它没有返回我期望的东西(迭代器超越时的非正值end()).你怎么能确保没有越级?
#include <iostream>
#include <iterator>
#include <list>
using namespace std;
int main () {
list<int> mylist;
for (int i=0; i<10; i++) mylist.push_back (i*10);
list<int>::const_iterator first = mylist.begin();
const list<int>::const_iterator last = mylist.end();
cout << "The distance is: " << distance(first,last) << endl; // 10
advance(first, 10);
cout << "The distance is: " << distance(first,last) << endl; // 0
advance(first, 1);
cout << "The distance is: " << distance(first,last) << endl; …Run Code Online (Sandbox Code Playgroud) 编辑:我有很多答案告诉我,我应该将删除分成另一个循环.也许我没有说清楚,但我在上一段中说过,我想找到一个解决方法.即保持当前的代码结构,但使用一些鲜为人知的C++ fu来使其工作.
好吧,我知道调用erase()一个向量会使元素的迭代器和它之后的所有迭代器失效,并且erase()会将迭代器返回到下一个有效的迭代器,但是如果擦除发生在其他地方呢?
我有以下情况(简化):
警告:不要认为这是整个代码.下面显示的内容非常简单,以说明我的问题.下面显示的所有类和方法实际上要复杂得多.
class Child {
Parent *parent;
}
class Parent {
vector<Child*> child;
}
void Parent::erase(Child* a) {
// find an iterator, it, that points to Child* a
child.erase(it);
}
int Child::update() {
if(x()) parent.erase(*this) // Sometimes it will; sometimes (most) it won't
return y;
}
void Parent::update() {
int i = 0;
for(vector<A>::iterator it = child.begin(); it != child.end(); it++)
i += (*it)->update();
}
Run Code Online (Sandbox Code Playgroud)
因此,很明显,(*it)->update()如果x()返回true ,它会在运行后崩溃,因为当它执行时,Child会告诉Parent将它从向量中移除,使迭代器无效.
有没有什么方法可以解决这个问题,而不是让Parent::erase() …
以下是返回迭代器的Java方法
vector<string> types;
// some code here
Iterator Union::types()
{
return types.iterator();
}
Run Code Online (Sandbox Code Playgroud)
我想将此代码翻译为C++.如何从此方法返回vector的迭代器?
我正在和一个人一起工作std::map<std::string, MyClass* >.
我想测试是否my_map.find(key)返回特定指针.
现在我正在做;
auto iter = my_map.find(key);
if ((iter != my_map.end()) && (iter->second == expected)) {
// Something wonderful has happened
}
Run Code Online (Sandbox Code Playgroud)
但是,operator *迭代器的位置需要返回引用.直觉我认为它是有效的并完全初始化?如果是这样,那my_map.end()->second将是NULL,并且(因为NULL从未预料到),我可以将我的if语句减少为:
if (iter->second == expected)
Run Code Online (Sandbox Code Playgroud)
这是否符合规范?有没有人有实际经验?恕我直言,代码变得更加清晰,可能会实现微小的性能提升.
我有一个枚举器类型:
enum PlayerProps {
Attempts;
Gold;
Diamonds;
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能遍历所有枚举值?就像是:
var props = new Map<PlayerProps, Int>();
for (prop in PlayerProps)
props[prop] = 0;
Run Code Online (Sandbox Code Playgroud) 处理const向量时,以下方法不起作用:
const std::vector<std::string> v;
v.push_back("test"); // error: v cannot be modified
Run Code Online (Sandbox Code Playgroud)
相反,您必须在构造它的同一行初始化向量.但是,即使有这个限制,boost::make_transform_iterator也可以在将它们推入v之前轻松地使用另一个vector的元素.在这个例子中,convert是一个返回输入元素的转换版本的一元函数:
auto beg = boost::make_transform_iterator(args.begin(), convert);
auto end = boost::make_transform_iterator(args.end(), convert);
const std::vector<const char*> vc { beg, end };
Run Code Online (Sandbox Code Playgroud)
我已经看了可用的功能<iterator>,但没有看到等效功能.它只是缺失或标准库没有它的原因吗?
让我们假设我有一个非常大的可迭代值集合(大约100,000个字符串条目,逐个从磁盘读取),我在其笛卡尔积上做了一些事情(并将结果写回磁盘,但我不会在这里显示):
for(v1 <- values; v2 <- values) yield ((v1, v2), 1)
Run Code Online (Sandbox Code Playgroud)
我知道这只是另一种写作方式
values.flatMap(v1 => values.map(v2 => ((v1, v2), 1)))
Run Code Online (Sandbox Code Playgroud)
这显然导致每个flatMap迭代(甚至整个笛卡尔积?)的整个集合保存在内存中.如果你使用for循环读取第一个版本,这显然是不必要的.理想情况下,只应将两个条目(正在组合的条目)保存在内存中.
如果我重新制定第一个版本:
for(v1 <- values.iterator; v2 <- values.iterator) yield ((v1, v2), 1)
Run Code Online (Sandbox Code Playgroud)
内存消耗要低很多,这让我认为这个版本必须根本不同.它在第二个版本中的确有何不同?为什么Scala不会隐式使用第一个版本的迭代器?在某些情况下不使用迭代器时是否有任何加速?
谢谢!(还要感谢"lmm"谁回答了这个问题的早期版本)
您可以使用解构分配来定义ES6中的枚举,如下所示:
var [red, green, blue] = [0, 1, 2];
Run Code Online (Sandbox Code Playgroud)
相反,我希望解构分配的右侧是动态的.例如:
var MAX_ENUM_SIZE = 32;
var ENUM = new Array(MAX_ENUM_SIZE);
for (var i = 0; i < MAX_ENUM_SIZE; i++) ENUM[i] = i;
var [red, green, blue] = ENUM;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这似乎是一个黑客.如果我希望将来有更大的枚举怎么办?因此,我正在考虑使用迭代器进行解构赋值,如下所示:
var [red, green, blue] = enumeration(/* I don't want to specify size */);
Run Code Online (Sandbox Code Playgroud)
但是,我不认为可以使用迭代器进行解构赋值[需要引证].有没有办法实现这个目标?