Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ STL列表-如何通过对象字段查找列表元素_C++_List_Stl - Fatal编程技术网

C++ STL列表-如何通过对象字段查找列表元素

C++ STL列表-如何通过对象字段查找列表元素,c++,list,stl,C++,List,Stl,我有一份清单: list<Unit *> UnitCollection; 如何通过uCode搜索UnitCollection列表并返回相应的元素和迭代器 在伪代码中,它看起来像这样: for every item in my UnitCollection: if the unit.isUnit(someUnitIpass) do something else next unit struct predicate { predicate( const

我有一份清单:

list<Unit *> UnitCollection;
如何通过uCode搜索UnitCollection列表并返回相应的元素和迭代器

在伪代码中,它看起来像这样:

for every item in my UnitCollection:
  if the unit.isUnit(someUnitIpass)
    do something
  else
    next unit
struct predicate
{
    predicate( const std::string &uCode ) : uCode_(uCode) {}

    bool operator() ( Unit *u )
    {
        return u->isUnit( uCode_ )
    }
private:
    std::string uCode_;
};
predicate pred("uCode");
std::list<Unit*>::iterator i;
i = std::find_if( UnitCollection.begin(), UnitCollection.end(), pred );
我已经研究了find方法,但是如果有意义的话,我不确定是否可以传入布尔方法而不是搜索项参数。

看看

如果可以使用boost,那么可以将其与boost::lambda一起使用

或者你可以编写自己的函子

struct isUnitor // : public std::unary_function<Unit*, bool> -- this is only needed for the negation below
{
  string arg;
  isUnitor(const string& s) : arg(s) {}
  bool operator()(Unit* u) const { return u->isUnit(arg); }
};

std::find_if(...begin... , ...end... , isUnitor("code"))
看一看

如果可以使用boost,那么可以将其与boost::lambda一起使用

或者你可以编写自己的函子

struct isUnitor // : public std::unary_function<Unit*, bool> -- this is only needed for the negation below
{
  string arg;
  isUnitor(const string& s) : arg(s) {}
  bool operator()(Unit* u) const { return u->isUnit(arg); }
};

std::find_if(...begin... , ...end... , isUnitor("code"))
您可以按照jpalecek的建议查看一下,然后使用查找从find_if返回的迭代器与UnitCollection.begin之间的距离,该距离应该是列表中元素的索引

对于谓词,您可以编写如下函数对象:

for every item in my UnitCollection:
  if the unit.isUnit(someUnitIpass)
    do something
  else
    next unit
struct predicate
{
    predicate( const std::string &uCode ) : uCode_(uCode) {}

    bool operator() ( Unit *u )
    {
        return u->isUnit( uCode_ )
    }
private:
    std::string uCode_;
};
predicate pred("uCode");
std::list<Unit*>::iterator i;
i = std::find_if( UnitCollection.begin(), UnitCollection.end(), pred );
然后像这样使用它:

for every item in my UnitCollection:
  if the unit.isUnit(someUnitIpass)
    do something
  else
    next unit
struct predicate
{
    predicate( const std::string &uCode ) : uCode_(uCode) {}

    bool operator() ( Unit *u )
    {
        return u->isUnit( uCode_ )
    }
private:
    std::string uCode_;
};
predicate pred("uCode");
std::list<Unit*>::iterator i;
i = std::find_if( UnitCollection.begin(), UnitCollection.end(), pred );
或者至少我认为这是一种方法。

您可以按照jpalecek的建议查看一下,然后使用查找if和UnitCollection.begin返回的迭代器之间的距离,该距离应该是列表中元素的索引

对于谓词,您可以编写如下函数对象:

for every item in my UnitCollection:
  if the unit.isUnit(someUnitIpass)
    do something
  else
    next unit
struct predicate
{
    predicate( const std::string &uCode ) : uCode_(uCode) {}

    bool operator() ( Unit *u )
    {
        return u->isUnit( uCode_ )
    }
private:
    std::string uCode_;
};
predicate pred("uCode");
std::list<Unit*>::iterator i;
i = std::find_if( UnitCollection.begin(), UnitCollection.end(), pred );
然后像这样使用它:

for every item in my UnitCollection:
  if the unit.isUnit(someUnitIpass)
    do something
  else
    next unit
struct predicate
{
    predicate( const std::string &uCode ) : uCode_(uCode) {}

    bool operator() ( Unit *u )
    {
        return u->isUnit( uCode_ )
    }
private:
    std::string uCode_;
};
predicate pred("uCode");
std::list<Unit*>::iterator i;
i = std::find_if( UnitCollection.begin(), UnitCollection.end(), pred );
或者至少我认为这是一种方法。

首先是一个无关紧要的评论 您可以将访问器函数更改为更简单的形式

return unitCode == uCode;
现在谈谈我们来这里的目的 最好是查找元素的位置,而不是其索引。从其索引获取元素是一个On操作,而从其位置获取元素是一个O1操作。因此,在STL和boost::bind的帮助下:

然后,您可以调用std::find_(如果愿意):

还有一点性能方面的考虑 还有一件事:我不知道uCode看起来是什么样子,但是如果它们很大,那么您可以通过维护这些字符串的哈希值来加快速度,以便在搜索谓词中只比较哈希值。散列可能是正则整数:比较整数非常快

另外一件事:如果你经常运行这个搜索过程,你也可以考虑改变容器类型,因为这确实是一个昂贵的过程:按照列表的长度顺序。

第一个无关紧要的评论。 您可以将访问器函数更改为更简单的形式

return unitCode == uCode;
现在谈谈我们来这里的目的 最好是查找元素的位置,而不是其索引。从其索引获取元素是一个On操作,而从其位置获取元素是一个O1操作。因此,在STL和boost::bind的帮助下:

然后,您可以调用std::find_(如果愿意):

还有一点性能方面的考虑 还有一件事:我不知道uCode看起来是什么样子,但是如果它们很大,那么您可以通过维护这些字符串的哈希值来加快速度,以便在搜索谓词中只比较哈希值。散列可能是正则整数:比较整数非常快


另外一件事:如果你经常运行这个搜索过程,你也可以考虑改变容器类型,因为这确实是一个昂贵的过程:按照列表的长度顺序。

你的谓词可能看起来像:

struct unit_predicate {
    unit_predicate(const string& s): str(s) {}
    bool operator()(const Unit* unit) const {
        return unit->isUnit(str);
    }
    const string& str;
};

UnitCollection::const_iterator unit = std::find_if(units.begin(), units.end(), unit_predicate("Some Unit"));
其他几点意见:

isUnit函数最好按常量引用获取字符串,以避免不必要的副本


你说你想返回一个项目的索引;对于链表来说,这通常是不合理的,因为您无法通过索引获取项目。如果您想通过索引处理它们,那么std::vector可能对您更有用。

您的谓词可能类似于:

struct unit_predicate {
    unit_predicate(const string& s): str(s) {}
    bool operator()(const Unit* unit) const {
        return unit->isUnit(str);
    }
    const string& str;
};

UnitCollection::const_iterator unit = std::find_if(units.begin(), units.end(), unit_predicate("Some Unit"));
其他几点意见:

isUnit函数最好按常量引用获取字符串,以避免不必要的副本


你说你想返回一个项目的索引;对于链表来说,这通常是不合理的,因为您无法通过索引获取项目。如果你想通过索引来处理它们,或许std::vector对你更有用。

我忘了提这一点,我还是被卡住了。我在find_if中使用什么谓词?该函数位于列表中包含的对象中。这个链接与我理想情况下需要的内容类似,我会使用boost,但我无法确定标准:我忘了提到这一点,我仍然被卡住了。我在find_if中使用什么谓词?该函数位于列表中包含的对象中。这个链接与我理想情况下需要的类似,我会使用boost,但我不能满足以下条件:索引和列表不能同时使用。最好返回迭代器或指针。索引和列表不能同时使用。您最好返回一个迭代器或指针。很遗憾,Boost不可用:@Dominic Bou Samra:然后使用bind2nd、mem\u fun\u ref和friends。@Billy ONeal看到了吗
我上面的最后一段。这些都不起作用,因为mem_-fun生成一元函数,函数的参数是调用函数的对象。mem_fun或其任何朋友都没有生成二进制函数的版本。当然,@Dominic可以做的是创建一个函数对象,该对象可以作为标准算法的独立对象,也可以选择使用中的任何标准适配器。这可能是你最好的方法。很遗憾,Boost不可用:@Dominic Bou Samra:然后使用bind2nd、mem_fun_ref和friends。@Billy ONeal查看我上面的最后一段。这些都不起作用,因为mem_-fun生成一元函数,函数的参数是调用函数的对象。mem_fun或其任何朋友都没有生成二进制函数的版本。当然,@Dominic可以做的是创建一个函数对象,该对象可以作为标准算法的独立对象,也可以选择使用中的任何标准适配器。这可能是你最好的方法。谢谢-这很好用。考虑到我的“做某事”是删除某个项目,我也可以使用可爱的“删除”按钮。是的,索引是愚蠢的,但它是一种满足似乎是最不真实的标准和代码规范的情况,使用他们告诉我们的。@Dominic:你必须使用列表吗?是的:我想使用VectorHanks-这非常有效。考虑到我的“做某事”是删除某个项目,我也可以使用可爱的“删除”按钮。是的,索引是愚蠢的,但它是一种满足似乎是最不真实的标准和代码规范的情况,使用他们告诉我们的。@Dominic:你必须使用列表吗?是的:我想使用向量