2017-09-27 6 views
0

Iは円形構造体及び円を格納するためのリストを持っている:C++でコールバック関数を使って値を返すことはできますか?

struct circle 
{ 
    float r; 
    int id; 
}; 
list<circle> circleList; 

Iは、円(半径とID)に関する情報をXML文書を解析し、リスト内で次に格納するTinyxmlを使用している(これは主な機能に)

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を使用し、それが動作しますが、円はリストに格納されています。しかし、コードのある時点では、各円の半径を取得する必要があります。ここで

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機能は半径を返す作るしようとしているので、私は理解して

が、何Iコールバック関数が半径を返すことが本当に必要なのか(やり方がわからないのですか)、この情報を取得しているのはコールバックです。

+1

エラーを表示すると役立ちます。 –

+6

あなたは 'for_each(circleList.begin()、circleList.end()、returnRadius);'と正確に何をしますか?各円はそれ自身の半径を持っているので返りますか? – NathanOliver

+0

@ NathanOliver各円の半径... for_eachは円のリストを反復し、returnRadiusは各半径を返します – jaryl

答えて

5

私はあなたが複雑すぎると言っていますもの。

for (const auto &it : circleList) 
{ 
    // Do whatever you wand with `it.r` here. 
} 
+0

正直言って、for_eachはリストを繰り返し処理しようとしていたので、私は使用していましたが、構造体データにアクセスできず、多くのエラーが発生しました。しかし、これはうまくいった。私が使用した構文はこれと非常に似ていたので、これは奇妙です。 – jaryl

+2

@jaryl: 'for_each'はきちんとしていますが、現実的には私はこれを使うことはありませんでした。通常の 'for'ループは、ほとんど常に良いです。 –

0

それはC言語で、コールバック関数が値を返す++作ることは可能ですか?

あなたのタイトルは質問の身体とはあまり関係ありませんが、私はそれに焦点を合わせており、通常の方法でcallbacksを理解しています。

これはC++のバージョンによって異なる場合があります。私はあなたが、あなたはlambda expressionsstd::function -sと<algorithm>

ここ

std::transformを使用して領域のリスト(実際std::list<float>)を取得する方法であるを持つことができる、少なくともC++ 11を使用して願っています(多くの場合、他のプログラミング言語でmapと呼ばれます)ラムダ式で:

auto areaList = std::transform(circleList.begin(), circleList.end(), 
           [] (const circle&c) 
           { return c.r*c.r*M_PI; }); 

(あなたはTinyXMLの事にそれを適応させることができるはずです)

あなたはC++ 11 programming book良いをお読みください。

あなたはSICPを読むことができたし、closureanonymous functions wikipages

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); 
関連する問題