我有一个圆形结构和一个存储圆圈的列表:
struct circle
{
float r;
int id;
};
list<circle> circleList;
我正在使用Tinyxml解析带有圆圈(半径和id)的信息的xml文档,然后将其存储在列表中:(这是在主函数中)
circle c;
for(TiXmlElement* e = objectTree; e != NULL; e = e->NextSiblingElement())
{
c.r = atof(e->Attribute("r"));
c.id = atoi(e->Attribute("id"));
circleList.push_back(c);
}
它运行正常,我使用for_each打印值并且它有效,圆圈存储在列表中。但在代码的某些方面,我需要得到每个圆的半径。我试着在main函数中执行此操作,就在将循环存储在列表中的for循环之后:
float radius = for_each(circleList.begin(), circleList.end(), returnRadius);
这是回调函数:
float returnRadius(circle &data)
{
return data.r;
}
但是我得到了很多错误,可能是因为我创建了一个名为radius的值,并尝试将for_each返回的值存储在其中,这是完全错误的,我知道。但我的目的是找到一种方法来获取回调函数returnRadius返回的值。有没有办法做到这一点?
当我尝试这样做时:
float radius = for_each(circleList.begin(), circleList.end(), returnRadius);
我收到这些错误:
error: cannot convert ‘float (*)(circle&)’ to ‘float’ in initialization
float radius = for_each(circleList.begin(), circleList.end(), returnRadius);
我理解,因为我试图让for_each函数返回半径,但我真正想要的(并且不知道该怎么做)是回调函数返回半径,毕竟,它是正在检索此信息的回调
答案 0 :(得分:5)
我说你过度复杂了。
for (const auto &it : circleList)
{
// Do whatever you wand with `it.r` here.
}
答案 1 :(得分:1)
float radius = for_each(circleList.begin(), circleList.end(), returnRadius);
for_each
不会返回任何内容。它为每个值调用returnRadius
,现在就完成了。正是你告诉它要做的事情。如果你想做的不仅仅是为每个项目调用returnRadius
,那么你已经向编译器谎报了你希望它为每个项目做些什么。
auto print_radius = [](const circle &data) {
std::cout << returnRadius(data) << '\n';
};
std::for_each(circleList.begin(), circleList.end(), print_radius);
一般来说,我会避免std::for_each
。它非常整洁,但令代码混淆不清。
<小时/> 如果您正在使用
std::for_each
,那么了解boost::transform_iterator
也很有趣。它是这样的:
//make iterators that transform circles to radius' on the fly
auto first = boost::make_transform_iterator(circleList.begin(), returnRadius);
auto last = boost::make_transform_iterator(circleList.end(), returnRadius);
//copy these radius' to cout.
std::copy(first, last, std::ostream_iterator(std::cout);
答案 2 :(得分:0)
是否可以在c ++中使回调函数返回一个值?
你的标题与问题的主体没什么关系,但我关注它,并以通常的方式理解callbacks。
这可能取决于您的C ++版本。我希望你至少使用C ++ 11,然后你可以拥有lambda expressions和std::function
- s和<algorithm>
以下是如何使用std::transform(在其他编程语言中通常称为map)使用lambda表达式获取区域列表(实际上是std::list<float>
):
auto areaList = std::transform(circleList.begin(), circleList.end(),
[] (const circle&c)
{ return c.r*c.r*M_PI; });
(你应该能够适应你的TinyXML)
你应该读一个好的C ++ 11 programming book。
您可以阅读SICP以及closure和anonymous functions wikipages