「BOOST FOREACH」の版間の差分

提供: C++入門
移動: 案内検索
 
(同じ利用者による、間の1版が非表示)
行1: 行1:
[[BOOST_FOREACH]] を使うことで、ループより簡単に記述できます。
+
[[Boost]]の[[BOOST_FOREACH]] を使うことで、ループより簡単に記述できます。
  
 
'''読み方'''
 
'''読み方'''
行7: 行7:
  
 
== 概要 ==
 
== 概要 ==
配列やコンテナをループで回すために、for文や[[イテレータ]]を書くのは面倒です。
+
配列やコンテナをループで回すために、[[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::[[map]] などを使うときです。
+
どういったときに、問題になるのかというと、 [[std::map]] などを使うときです。
  
 
対策として、 [[typedef]] を利用します。
 
対策として、 [[typedef]] を利用します。
行74: 行69:
  
 
=== Iterator を無効化してはいけない ===
 
=== Iterator を無効化してはいけない ===
 
 
このようなコードを書いてはいけません。
 
このようなコードを書いてはいけません。
ループを終了するための [[Iterator]] の end() を無効化してしまうようです。
+
ループを終了するための 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時点における最新版

BoostBOOST_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!
}

関連項目