「BOOST FOREACH」の版間の差分
提供: C++入門
(同じ利用者による、間の1版が非表示) | |||
行1: | 行1: | ||
− | [[BOOST_FOREACH]] を使うことで、ループより簡単に記述できます。 | + | [[Boost]]の[[BOOST_FOREACH]] を使うことで、ループより簡単に記述できます。 |
'''読み方''' | '''読み方''' | ||
行7: | 行7: | ||
== 概要 == | == 概要 == | ||
− | + | 配列やコンテナをループで回すために、[[for]]文や[[イテレータ]]を書くのは面倒です。 | |
特に、[[イテレータ]]は、かなり面倒ではないでしょうか。 | 特に、[[イテレータ]]は、かなり面倒ではないでしょうか。 | ||
もっと、簡単に書く方法があります。 [[Boost]] の foreach を使うことです。 | もっと、簡単に書く方法があります。 [[Boost]] の foreach を使うことです。 | ||
+ | [[C++11]]で拡張された[[for]]と追加された[[auto]]を使って、簡単に書くこともできます。 | ||
== ヘッダファイル == | == ヘッダファイル == | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
#include <boost/foreach.hpp> | #include <boost/foreach.hpp> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
== ソースコード == | == ソースコード == | ||
− | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
#include <boost/foreach.hpp> | #include <boost/foreach.hpp> | ||
行45: | 行44: | ||
== コンパイル == | == コンパイル == | ||
− | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
clang++ -I/usr/local/include for_each.cpp | clang++ -I/usr/local/include for_each.cpp | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
== 注意するべきこと == | == 注意するべきこと == | ||
− | |||
=== カンマは1つだけしか使えない === | === カンマは1つだけしか使えない === | ||
− | |||
BOOST_FOREACH は、マクロで実装されています。 | BOOST_FOREACH は、マクロで実装されています。 | ||
そのため、BOOST_FOREACHのカッコの中では、カンマは1つでなければなりません。 | そのため、BOOST_FOREACHのカッコの中では、カンマは1つでなければなりません。 | ||
− | どういったときに、問題になるのかというと、 std:: | + | どういったときに、問題になるのかというと、 [[std::map]] などを使うときです。 |
対策として、 [[typedef]] を利用します。 | 対策として、 [[typedef]] を利用します。 | ||
行74: | 行69: | ||
=== Iterator を無効化してはいけない === | === Iterator を無効化してはいけない === | ||
− | |||
このようなコードを書いてはいけません。 | このようなコードを書いてはいけません。 | ||
− | ループを終了するための | + | ループを終了するための Iterator の end() を無効化してしまうようです。 |
振る舞いが未定義となります。 | 振る舞いが未定義となります。 | ||
行87: | 行81: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | 上記のコードは、[[ | + | 上記のコードは、[[コンパイラ]]によって以下のように展開されます。 |
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
std::vector<int> vect(4, 4); | std::vector<int> vect(4, 4); | ||
行97: | 行91: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
== 関連項目 == | == 関連項目 == | ||
* [[Boost]] | * [[Boost]] | ||
* [[C++ライブラリ]] | * [[C++ライブラリ]] | ||
+ | * [[for]] | ||
+ | * [[C++11]] | ||
<!-- | <!-- | ||
vim: filetype=mediawiki | vim: filetype=mediawiki | ||
--> | --> |
2015年10月31日 (土) 21:31時点における最新版
BoostのBOOST_FOREACH を使うことで、ループより簡単に記述できます。
読み方
- BOOST_FOREACH
- ぶーすと ふぉーいーち
概要
配列やコンテナをループで回すために、for文やイテレータを書くのは面倒です。 特に、イテレータは、かなり面倒ではないでしょうか。
もっと、簡単に書く方法があります。 Boost の foreach を使うことです。
C++11で拡張されたforと追加されたautoを使って、簡単に書くこともできます。
ヘッダファイル
#include <boost/foreach.hpp>
ソースコード
#include <boost/foreach.hpp> #include <iostream> #include <vector> #include <string> using namespace std; int main(int argc, char const* argv[]) { vector<string> v; v.push_back ("a"); v.push_back ("b"); v.push_back ("c"); BOOST_FOREACH(string s, v) { cout << s << endl; } return 0; }
コンパイル
clang++ -I/usr/local/include for_each.cpp
注意するべきこと
カンマは1つだけしか使えない
BOOST_FOREACH は、マクロで実装されています。 そのため、BOOST_FOREACHのカッコの中では、カンマは1つでなければなりません。 どういったときに、問題になるのかというと、 std::map などを使うときです。
対策として、 typedef を利用します。
プログラムの例は、以下の通りです。
typedef std::pair<string, vector<ColumnOrSuperColumn> > PAIR; void foo( map<string, string > & data) { BOOST_FOREACH(PAIR p, data) { cout << p.first << endl; cout << p.second << endl; } }
Iterator を無効化してはいけない
このようなコードを書いてはいけません。 ループを終了するための Iterator の end() を無効化してしまうようです。 振る舞いが未定義となります。
std::vector<int> vect(4, 4); BOOST_FOREACH(int i, vect) { vect.push_back(i + 1); }
上記のコードは、コンパイラによって以下のように展開されます。
std::vector<int> vect(4, 4); for(std::vector<int>::iterator it1 = vect.begin(), it2 = vect.end(); it1 != it2; ++it1) { int i = *it1; vect.push_back(i + 1); // Oops! This invalidates it1 and it2! }