是否可以为现有的POD类型元素数组创建类似STL的容器,甚至只是STL样式的迭代器?
例如,假设我有一个int数组.能够直接在此数组上调用某些STL函数(例如find_if,count_if或sort)会很方便.
非解决方案:复制整个数组,甚至只是引用元素.目标是节省内存和时间,同时希望允许使用其他STL算法.
我最近了解了在C++中使用反向迭代器的正确方法(特别是当你需要擦除它时).(见这个问题,并且这一个.)
这就是你应该这样做的方式:
typedef std::vector<int> IV;
for (IV::reverse_iterator rit = iv.rbegin(), rend = iv.rend();
rit != rend; ++rit)
{
// Use 'rit' if a reverse_iterator is good enough, e.g.,
*rit += 10;
// Use (rit + 1).base() if you need a regular iterator e.g.,
iv.erase((rit + 1).base());
}
Run Code Online (Sandbox Code Playgroud)
但我认为这样做要好得多(不要这样做,不符合标准,正如MooingDuck指出的那样):
for (IV::iterator it = iv.end(), begin = iv.begin();
it-- != begin; )
{
// Use 'it' for anything you want
*it += 10;
iv.erase(it); …Run Code Online (Sandbox Code Playgroud) 我在第8行有一个运行时错误"map/set iterators incompatible".
void Manager::Simulate(Military* military, Shalishut* shalishut,char* args[]){
Simulation* simulation = Simulation::GetInstance();
Time* time = Time::GetInstance();
multimap<int,Task*>::iterator itTasks;
itTasks = simulation->GetTasks().begin();
while(itTasks != simulation->GetTasks().end()){
while (itTasks->second->GetTimeStamp() == time->GetTime()){ /*line 8 - ERROR*/
TaskExecute(itTasks->second,military,shalishut,args);
itTasks++;
}
// Unit take car of vehicles
time->TimeIncrease();
}
}
Run Code Online (Sandbox Code Playgroud)
Simulation被宣布为multimap<int,Task*>.问题是什么?
我已经尝试了我的G ++版本的C++ 0x初始化列表实现,但它只输出空行.
#include <initializer_list>
#include <iostream>
#include <string>
int main() {
std::initializer_list<std::string> a({"hello", "stackoverflow"});
for(auto it = a.begin(), ite = a.end(); it != ite; ++it)
std::cout << *it << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我不知道我做错了什么.有人可以帮帮我吗?
我一直认为"奇异"迭代器是一个默认初始化的迭代器,它们可以作为类似的哨兵值:
typedef std::vector<Elem>::iterator I;
I start = I();
std::vector<Elem> container = foo();
for (I it = container.begin(), end = container.end(); it != end; ++it) {
if ((start == I()) && bar(it)) {
// Does something only the first time bar(it) is satisfied
// ...
start = it;
}
}
Run Code Online (Sandbox Code Playgroud)
但这个答案不仅表明我对"单数"的定义是错误的,而且我上面的比较完全是非法的.
是吗?
阅读工作草案N3337-1,编程语言C++标准,24.2.5转发迭代器,第806页.
来自草案:
两个可解除引用的迭代器a和b类型X提供了多次通过保证,如果:
- a == bimplies ++a == ++b和
- X是指针类型或表达式(void)++X(a), *a等价于表达式*a.
[注意:a == b暗示的要求++a == ++b(对于输入和输出迭代器不是这样)以及通过可变迭代器(适用于输出迭代器)去除对赋值数量的限制允许使用多遍 -具有前向迭代器的定向算法. - 尾注]
有人可以用更简单的术语重新解读这个吗?我知道Forward迭代器是多遍的,但我不明白这是如何根据C++标准要求完成的.
所述<algorithm>头部提供std::equal_range(),以及具有作为它的成员函数的一些容器.让这个函数困扰我的是它返回一对迭代器,使得从开始迭代器迭代到结束迭代器变得繁琐.我希望能够使用std::begin(),std::end()以便我可以使用基于C++ 11范围的for循环.
现在,我听到关于矛盾的信息,以专业std::begin()和std::end()-我已经被告知,添加什么不确定的行为std命名空间的结果,而我也被告知,你可以提供自己的专长std::begin()和std::end().
这就是我现在正在做的事情:
namespace std
{
template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category>
Iter begin(pair<Iter, Iter> const &p)
{
return p.first;
}
template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category>
Iter end(pair<Iter, Iter> const &p)
{
return p.second;
}
}
Run Code Online (Sandbox Code Playgroud)
这确实有效:http://ideone.com/wHVfkh
但我想知道,这样做的缺点是什么?有一个更好的方法吗?
这段代码有什么问题?
l = [1,2,3,4,5,6]
for val in iter(l, 4):
print (val)
Run Code Online (Sandbox Code Playgroud)
它回来了
TypeError: iter(v, w): v must be callable
Run Code Online (Sandbox Code Playgroud)
为什么callable(list)返回True但可调用(l)不是?
编辑 这里应该首选哪种方法:
我一直试图将invRegex.py移植到node.js实现一段时间,但我仍然在努力解决它.由于ret.js标记器,我已经有了正则表达式解析树,并且它工作得很好,但是以一种节省内存的方式实际生成和连接所有不同的元素对我来说是非常具有挑战性的.为了简单起见,我可以说我有以下正则表达式:
[01]{1,2}@[a-f]
Run Code Online (Sandbox Code Playgroud)
提供以invRegex.py产生以下输出(标签化以占用更少的空间):
0@a 0@b 0@c 0@d 0@e 0@f
00@a 00@b 00@c 00@d 00@e 00@f
01@a 01@b 01@c 01@d 01@e 01@f
1@a 1@b 1@c 1@d 1@e 1@f
10@a 10@b 10@c 10@d 10@e 10@f
11@a 11@b 11@c 11@d 11@e 11@f
Run Code Online (Sandbox Code Playgroud)
考虑到我能够获得每个单独的令牌并生成所有有效单个输出的数组:
[01]{1,2} = function () {
return ['0', '00', '01', '1', '10', '11'];
};
@ = function () {
return ['@'];
};
[a-f] = function () {
return ['a', 'b', 'c', 'd', 'e', …Run Code Online (Sandbox Code Playgroud) 我正在寻找一种简单的方法来为mapC++ 11中的a值创建一个迭代器.
这个方法应该简单透明:简单,因为它应该易于实现,并且透明,因为客户端不应该知道值来自地图而不是集合.
之前已经多次询问过这个问题.其中许多问题早于C++ 11并使用boost,我不想使用它.有些并不简单,John Ahlgren的解决方案,例如http://john-ahlgren.blogspot.com/2013/10/how-to-iterate-over-values-of-stdmap.html,例如需要一页代码编写自定义迭代器.
其他人不透明,即显然可以写:
map<string,foo> mymap;
for (auto it=mymap.begin();it!=mymap.end();++it){
Foo val= it->second;
...
}
Run Code Online (Sandbox Code Playgroud)
但是,我不想这样做,因为我不希望客户端必须知道数据表示.
问题出现如下.
我有一堆用长"钥匙"唯一索引的对象.有时我想操纵这些对象的集合.其他时候我想要检索一个给定键的对象.
我不能直接使用"set"类有几个原因,其中主要是它不存储可变实例,并且这些实例必须是可变的(显然,除了键之外).
所以,我决定将所有对象存储在一个巨大的全局哈希表中:
map<long,Foo> all_the_objects;
Run Code Online (Sandbox Code Playgroud)
然后我根本不工作set<Foo>.相反,我使用set<long>并使用适配器来模拟一组Foo,即
class SetOfFoo{
private: set<long> theKeys;
public:
void insert(const & Foo);
size_t size() return theKeys.size();
bool is_member(const & Foo)
{return theKeys.find(Foo.key)
!= theKeys.end;}
Foo & insert(const & Foo val){
long key=val.key;
all_the_objects[key]=val;
return all_the_objects[key];
}
...::iterator begin() {???}
}
Run Code Online (Sandbox Code Playgroud)
换句话说,SetOfFoo类的客户端不知道或不需要知道SetOfFoo是作为一组键实现的.
我也不能在适配器类中自己创建一个Vector,因为无法在C++集合中存储引用.
是否真的不可能以简单,透明的方式迭代map <>值?我觉得很难相信,因为这是一个非常普遍的需求,并且在我看到的每种语言中都有微不足道的事情.我只是不明白这怎么可能很难.