C++ 如何通过引用将存储在列表中的结构成员传递给函数?

C++ 如何通过引用将存储在列表中的结构成员传递给函数?,c++,list,function,struct,C++,List,Function,Struct,我有一个用结构填充STL链表的程序,我试图从列表上的节点(我当前通过迭代器访问的节点)传递结构成员。我试图完成的一件事是一个计算运行平均值的函数。我不想将计数和总数存储在结构中,然后在输出时计算平均值,而是希望将计数和平均值存储在结构中,从而在重新计算平均值后丢弃数量值。我的结构如下所示: struct mystruct { string item; long avg; short count; } data; void DoSomething(X& obje

我有一个用结构填充STL链表的程序,我试图从列表上的节点(我当前通过迭代器访问的节点)传递结构成员。我试图完成的一件事是一个计算运行平均值的函数。我不想将计数和总数存储在结构中,然后在输出时计算平均值,而是希望将计数和平均值存储在结构中,从而在重新计算平均值后丢弃数量值。我的结构如下所示:

struct mystruct 
{
    string item;
    long avg;
    short count;
} data;
void DoSomething(X& object) {
  object.count, object.avg;
}
void DoSomethingElse(int& count, int& average) {
  ...
}

int main() {
   ...
   for(std::list<X>::iterator it=myList.begin(), end=myList.end(); it != end; ++it) {
     DoSomething(*it); // how I'd do it
     DoSomethingElse(it->count, it->avg); // Equally valid way that you did it
   }
   ...
}
这些结构存储在一个列表中,带有一个迭代器,
it
,允许我在列表中移动。如果我遍历了列表并且
it
等于要计算平均值的节点,那么这是调用平均值函数的正确方法吗

// prior to running the code below, the `count` and `avg` members for the 
// struct at iterator location `it` are both 1 and 100 respectively

long qty = 50;
calc_average(it->count, it->avg, qty);

cout << "The current count is " << it->count << endl; 
  // Outputs 'The current count is 2'
cout << "The current average is " << it->avg << endl; 
  // Outputs 'The current average is 75'


void calc_average(short &count, long &avg, long quant)
{
    avg = ( (avg * count) + quant ) / (count + 1);
    count++;
}
//在运行下面的代码之前
//迭代器位置'it'处的结构分别为1和100
长数量=50;
计算平均值(it->计数,it->平均值,数量);

cout假设
X
是列表中对象的类型,则可以执行以下操作:

struct mystruct 
{
    string item;
    long avg;
    short count;
} data;
void DoSomething(X& object) {
  object.count, object.avg;
}
void DoSomethingElse(int& count, int& average) {
  ...
}

int main() {
   ...
   for(std::list<X>::iterator it=myList.begin(), end=myList.end(); it != end; ++it) {
     DoSomething(*it); // how I'd do it
     DoSomethingElse(it->count, it->avg); // Equally valid way that you did it
   }
   ...
}

假设
X
是列表中对象的类型,则可以执行以下操作:

struct mystruct 
{
    string item;
    long avg;
    short count;
} data;
void DoSomething(X& object) {
  object.count, object.avg;
}
void DoSomethingElse(int& count, int& average) {
  ...
}

int main() {
   ...
   for(std::list<X>::iterator it=myList.begin(), end=myList.end(); it != end; ++it) {
     DoSomething(*it); // how I'd do it
     DoSomethingElse(it->count, it->avg); // Equally valid way that you did it
   }
   ...
}

将迭代器视为指向列表中某个元素的指针。因此,与其让
calc_average
函数作用于
mystruct
的单个成员,不如让它引用
mystruct
对象并对其进行处理

例如:

void do_work( mystruct& s )
{
  ++s.count;
}

std::list<mystruct> mylist;

// populate list

std::for_each( mylist.begin(), mylist.end(), do_work );
我会将
calc\u average
函数重写为

void calc_average( mystruct& s, long quant )
{
    s.avg = ( (s.avg * s.count) + quant ) / (s.count + 1);
    s.count++;
}
将它与基于范围的
for
循环一起使用并不重要,但要将它与
std::for_each
一起使用,您必须使用
std::bind
来绑定
quant
参数

std::for_each( mylist.begin(), mylist.end(), 
  std::bind( calc_average, std::placeholders::_1, qty ) );

将迭代器视为指向列表中某个元素的指针。因此,与其让
calc_average
函数作用于
mystruct
的单个成员,不如让它引用
mystruct
对象并对其进行处理

例如:

void do_work( mystruct& s )
{
  ++s.count;
}

std::list<mystruct> mylist;

// populate list

std::for_each( mylist.begin(), mylist.end(), do_work );
我会将
calc\u average
函数重写为

void calc_average( mystruct& s, long quant )
{
    s.avg = ( (s.avg * s.count) + quant ) / (s.count + 1);
    s.count++;
}
将它与基于范围的
for
循环一起使用并不重要,但要将它与
std::for_each
一起使用,您必须使用
std::bind
来绑定
quant
参数

std::for_each( mylist.begin(), mylist.end(), 
  std::bind( calc_average, std::placeholders::_1, qty ) );

是的,在我看来这一切都是正确的。您可以将迭代器(尤其是标准容器的迭代器)视为指针,尽管实际上它们是看起来像指针的类。不过,你可以把它们看作是指针。

是的,在我看来这一切都是正确的。您可以将迭代器(尤其是标准容器的迭代器)视为指针,尽管实际上它们是看起来像指针的类。不过,您可以将它们视为指针。

我目前正在处理动态内容,我发现 我有一个精灵结构 std::列出字符\u spr; 我通过精灵字符声明一个字符,然后使用

characters_spr.push_back(character)
然后 我使用for循环来迭代列表

for(SPRITE &character : characters_spr){
   somefunction(character, ....);
}
在我的函数中 somefunction(精灵和spr…)


当调用somefunction时,它会更新列表中角色的角色数据。

我目前正在处理动态内容,我发现 我有一个精灵结构 std::列出字符\u spr; 我通过精灵字符声明一个字符,然后使用

characters_spr.push_back(character)
然后 我使用for循环来迭代列表

for(SPRITE &character : characters_spr){
   somefunction(character, ....);
}
在我的函数中 somefunction(精灵和spr…)


调用somefunction时,它会更新列表中字符的字符数据。

谢谢,这很有帮助。不过,让我澄清一下。我不是遍历列表并在每个节点上运行
calc_average
,而是遍历列表以查找特定的
值。找到感兴趣的节点后,我将调用该特定节点上的
calc#u average
函数,将其称为列表中的节点5。在我写这篇文章时,我认为你的建议仍然有效,对吗?我只是不需要为
循环设置
。相反,我会到达我想要的迭代器,并通过
*it
将其传递给
void DoSomething
?今晚晚些时候我会试试这个,但是这个很有用!还有一个问题……如果我进行类似于
DoSomething(it)
的函数调用,它会通过值传递指向的元素吗?我问这个问题是因为我有另一个输出函数,其中没有任何内容被写入结构,而是将成员值打印到屏幕上。Thx
DoSomething(it)
将通过迭代器<代码>DoSomething(*it)
将把指向的元素传递给元素。它们是通过值传递还是通过引用传递的问题取决于
DoSomething()
的签名:
DoSeomthing(X)
通过值接收对象<代码>DosSeomthing(X&X)通过引用接收
DoSomething(std::list::iterator it)
按值接收迭代器
DoSomething(std::list::iterator&it)
通过引用接收迭代器。在您描述的情况下,我将声明
DoSomething(const X&X){X.count,X.value,}
并调用它:
DoSomething(*it)
。现在尝试所有这些,效果非常好。我在我的代码中使用了
std::list::iterator it
,虽然它起作用,但它更难阅读,我也不完全理解它在做什么。你上面的解释真的很有帮助。根据您最后的评论,您是否建议我将其用于输出函数?抱歉,只是不确定您指的是哪一个“案例”。谢谢,这很有帮助。不过,让我澄清一下。我不是遍历列表并在每个节点上运行
calc_average
,而是遍历列表