我一直在实现一个准确的观察者模式,并且陷入了一个有点神秘的错误:"成员引用基类型'Observer*'不是结构或联合".我认为这与我使用模板有关,我仍然相当不舒服.这是有问题的代码(为了简化事情,删除了大多数缺点/析构函数):
主题界面:
class Subject {
public:
virtual void notify();
private:
list< Observer * > m_observers;
};
Run Code Online (Sandbox Code Playgroud)
主题实施:
void Subject::notify() {
list< Observer * >::iterator i;
for ( i = m_observers.begin(); i != m_observers.end(); i++ ) {
*i->update( this ); // ERROR !!! ERROR
}
Run Code Online (Sandbox Code Playgroud)
观察者抽象界面:
class Observer {
public:
virtual ~Observer();
virtual void update( Subject * changedSubject ) = 0;
protected:
Observer();
};
Run Code Online (Sandbox Code Playgroud)
具体观察者界面:
class ConcreteObserver: public Observer {
public:
ConcreteObserver( ConcreteSubject * );
virtual ~ConcreteObserver();
virtual void update( Subject …Run Code Online (Sandbox Code Playgroud) 我正在寻找符合以下标准的数据结构(或数据结构组合)的C++实现:
O(log(n))复杂O(log(n))复杂性O(log(n))提前感谢您的任何建议
DALIBOR
(编辑)答案:
我选择的答案描述了满足所有这些要求的数据结构.然而,正如Maxim Yegorushkin所建议的那样,boost :: multi_index提供的功能非常接近上述功能.
(编辑)未正确指定某些要求.他们根据更正修改(:原创)
(编辑)我发现了接受的答案中描述的数据结构的实现.到目前为止,它按预期工作.它被称为计数器树
(编辑)考虑使用sp2danny建议的AVL-Array
我正在尝试编译ZipStream库,它是effectivley的一个用于zlib的C++包装器.
现在我正处于这两行的两个编译错误的位置:
std::set<file_info_32*, sort_by_offset>::iterator first = _core->_entries_by_name.begin();
std::set<file_info_32*, sort_by_offset>::iterator last = _core->_entries_by_name.end();
Run Code Online (Sandbox Code Playgroud)
错误是:
错误15错误C2440 ::
'initializing'无法转换
'std::_Tree_const_iterator<_Mytree>'为
'std::_Tree_const_iterator<_Mytree>'c:\ users\ahakeem\desktop\zipstream\ziparchive.cpp 423 1 zipstream
错误16错误C2440 ::'initializing'无法转换
'std::_Tree_const_iterator<_Mytree>'为
'std::_Tree_const_iterator<_Mytree>'c:\ users\ahakeem\desktop\zipstream\ziparchive. cpp 424 1 zipstream
所以基本上编译器说它无法转换'std::_Tree_const_iterator<_Mytree>'为'std::_Tree_const_iterator<_Mytree>'
任何想法为什么会发生以及如何解决?
编辑:在进一步调查之后,我发现它_core->entries_by_name.begin()被声明为'std::set<file_info_32*, sort_by_offset>',这显然与迭代器试图分配给(std::set<file_info_32*, sort_by_offset>)的内容不一致.
将其切换为_core->_entries_by_offset.begin();有效,因为它_entries_by_offset是与受让人期望获得的类型一致的类型.
这是否意味着有人可能破坏了代码,没有意识到并将其上传到源代码库?或者,这种错误分配的场景是否真的可以在某些系统上编译?
在我的头文件中,我已经包含了std :: map并使用了相应的命名空间.
我的一位成员是:
map<unsigned int, double> pT_Spam;
Run Code Online (Sandbox Code Playgroud)
在我的.cpp文件中,我尝试做一些我经常做一段时间的事情:
for(map<unsigned int, double>::iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++) {/*code*/}
Run Code Online (Sandbox Code Playgroud)
在cplusplus.com上使用std :: map的例子中甚至提到了上述内容.即使我在代码的其他部分中完成了相同的操作,导致没有编译错误,但在这个特定的行上,我从Cygwin得到以下错误:
error: conversion from `std::_Rb_tree_const_iterator<std::pair<const unsigned int, double> >' to non-scalar type `std::_Rb_tree_iterator<std::pair<const unsigned int, double> >' requested
Run Code Online (Sandbox Code Playgroud)
这似乎很奇怪.知道什么可能是错的吗?(我的标题当然包含在我的.cpp中)
在Python 3中,如何检查对象是否是容器(而不是只允许一次传递的迭代器)?
这是一个例子:
def renormalize(cont):
'''
each value from the original container is scaled by the same factor
such that their total becomes 1.0
'''
total = sum(cont)
for v in cont:
yield v/total
list(renormalize(range(5))) # [0.0, 0.1, 0.2, 0.3, 0.4]
list(renormalize(k for k in range(5))) # [] - a bug!
Run Code Online (Sandbox Code Playgroud)
显然,当renormalize函数接收到生成器表达式时,它不能按预期工作.它假设它可以多次遍历容器,而生成器只允许一次通过它.
理想情况下,我想这样做:
def renormalize(cont):
if not is_container(cont):
raise ContainerExpectedException
# ...
Run Code Online (Sandbox Code Playgroud)
我该如何实施is_container?
我想我可以检查参数是否为空,因为我们正在开始第二次通过它.但是这种方法不适用于更复杂的功能,在第二次传递开始的时候并不明显.此外,我宁愿将验证放在函数入口处,而不是放在函数内部(并在修改函数时将其移动).
我当然可以renormalize使用一次通过迭代器重写函数以正常工作.但这需要将输入数据复制到容器中.复制数以百万计的大型列表"以防它们不是列表"的性能影响是荒谬的.
编辑:我的原始示例使用了一个weighted_average函数:
def weighted_average(c):
'''
returns weighted average …Run Code Online (Sandbox Code Playgroud) 我写了一个非常简单的文件管理数据库,基本上看起来像这样:
class FileDB
{
public:
FileDB(std::string dir) : rootDir(dir) { }
void loadFile(std::string filename, File &file) const;
void saveFile(std::string filename, const File &file) const;
private:
std::string rootDir;
}
Run Code Online (Sandbox Code Playgroud)
现在我想迭代遍历数据库中包含的所有文件,例如使用std::iterator:
void iterateFiles()
{
FileDB filedb("C:\\MyFiles");
for (FileDB::iterator file_it = filedb.begin(); file_it != filedb.end(); ++file_it)
{
File f = *file_it;
// do something with file
}
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读了类似问题的答案,有些人建议推导std::iterator,有些人要使用std::iterator_traits,但我真的不明白该怎么做.尝试实现自定义迭代器时可能出现什么问题?什么是简单而优雅的方式呢?
编辑: 请不要考虑使用提升,我的问题更具概念性.
编辑2:
FileDB的工作方式如下:
ROOTDIR
foo2的
欢
barM中
所以基本上,我可以通过它的名字找到一个文件.
由于我的容器不在内存中,因此我没有指向其数据的指针.所以我的想法是将文件的路径存储在迭代器中.这样,我可以 …
我正在尝试遍历列表,我需要在迭代到达列表末尾时执行特定操作,请参阅下面的示例:
data = [1, 2, 3]
data_iter = data.__iter__()
try:
while True:
item = data_iter.next()
try:
do_stuff(item)
break # we just need to do stuff with the first successful item
except:
handle_errors(item) # in case of no success, handle and skip to next item
except StopIteration:
raise Exception("All items weren't successful")
Run Code Online (Sandbox Code Playgroud)
我相信这段代码不是Pythonic,所以我正在寻找更好的方法.我认为理想的代码应该看起来像下面的假设:
data = [1, 2, 3]
for item in data:
try:
do_stuff(item)
break # we just need to do stuff with the first successful item
except:
handle_errors(item) # in …Run Code Online (Sandbox Code Playgroud) 我有一个带有一些对象组合的模型类,我不知道为此编写迭代器的最佳方法.要更详细地查看问题,这里是层次结构(半伪代码):
Root类:
MYEntity : NSObject
@property int commonProperty;
@property NSArray *childs; //Childs of any kind.
Run Code Online (Sandbox Code Playgroud)
一些具体的子类:
MYConcreteStuff : MYEntity
@property int number;
MYConcreteThing : MYEntity
@property NSString *string;
Run Code Online (Sandbox Code Playgroud)
并且具有具体集合的根对象:
MYRoot : MYEntity
@property MYEntity *stuff; //Collect only stuff childs here.
@property MYEntity *things; //Collect only thing childs here.
Run Code Online (Sandbox Code Playgroud)
现在我可以为集合编写很酷的成员访问器(在MYEntity中),如:
-(MYEntity*)entityForIndex:(int) index
{
if ([self.childs count] > index)
return [self.childs objectAtIndex:index];
return nil;
}
Run Code Online (Sandbox Code Playgroud)
对于根对象,甚至更酷,良好类型的成员成员访问器.
-(MYConcreteThing*)thingForIndex:(int) index
{
if ([self.things count] > index)
return (MYConcreteThing*)[self.things entityForIndex];
return nil;
}
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何为这样的集合编写一些oneliner迭代器.想要的客户端代码如下:
for …Run Code Online (Sandbox Code Playgroud) 我们可以在C++中使用remove_if来基于对元素进行操作的谓词在线性时间中从向量中移除元素.
bool condition(double d) {...}
vector<double> data = ...
std::remove_if (data.begin(), data.end(), condition);
Run Code Online (Sandbox Code Playgroud)
如果我的条件不依赖于价值,而是依赖指数怎么办?换句话说,如果我想删除所有奇数索引元素,或某些任意索引集等?
bool condition(int index) {//returns whether this index should be removed}
vector<double> data = ...
std::remove_if (data.begin(), data.end(), ???);
Run Code Online (Sandbox Code Playgroud) 我想System.Array在IronPython中添加(算术)两个大元素元素并将结果存储在第一个数组中,如下所示:
for i in range(0:ArrA.Count) :
arrA.SetValue(i, arrA.GetValue(i) + arrB.GetValue(i));
Run Code Online (Sandbox Code Playgroud)
但是,这似乎很慢.有C背景我想使用指针或迭代器.但是,我不知道如何快速应用IronPython习语.我不能使用Python列表,因为我的对象严格来自System.Array类型.类型是3d浮点数.
什么是紧固件/计算此计算的快速方法?
编辑:
iterator ×10
c++ ×6
list ×2
python ×2
casting ×1
collections ×1
indexing ×1
ios ×1
ironpython ×1
map ×1
objective-c ×1
python-3.x ×1
remove-if ×1
std ×1
system.array ×1
templates ×1
types ×1
vector ×1
zipstream ×1