C++でLINQライクな処理(LINQ for C++による方法)

LINQ for C++

LINQは.NET Framework3.5から組み込まれた機能で,C#等の言語でSQLのデータベース操作のようなことを可能とする.「C# is LINQ」と言う方までいほどに便利な機能.

しかし,C++/CLIはLINQに対応する予定はないとのこと.そこで,LINQに似た機能をC++に提供してくれるのがLINQ for C++である.というわけでLINQ for C++を使ってみる.

導入

LINQ for C++はヘッダファイルひとつで実装されているので,以下のページからダウンロードしてきてインクルードするだけで使用できる.NuGetからのインストールも取得可能である.

LINQ for C++ - Home

使用例1

以下に使用例を示す.LINQ for C++を使って,テストの成績のうち国語と英語がともに50点以上の人のリストを取得している.

普通の配列に対して使うことが出来る.コード補完も微妙だし,型明記しなくちゃいけないし,メソッド形式ないしでC#のLINQほど軽快には書けないものの,便利ではある.

#include <cpplinq.hpp>

void main()
{
	using namespace cpplinq;

	struct Seiseki
	{
		char Name[256];
		int Kokugo;
		int Sansuu;
		int Eigo;
		int Rika;
		int Shakai;
	};

	Seiseki seisekiList[] = 
	{
		{"Yamada",98,78,61,83,70},
		{"Tanaka",20,33,16,39,48},
		{"Yoshida",72,65,92,13,26},
		{"Suzuki",49,82,55,11,96},
		{"Sasaki",83,47,61,23,60}
	};
	
	auto result = from_array(seisekiList)
		>> where([](Seiseki s) {return s.Kokugo > 50 && s.Eigo > 50;})
		>> to_vector();

	for (int i = 0; i < result.size();  ++ i)
		printf("%s : 国語%d 英語%d\n", result[i].Name, result[i].Kokugo, result[i].Eigo);
}

結果は以下のように表示される.

Yamada : 国語98 英語61
Yoshida : 国語72 英語92
Sasaki : 国語83 英語61

使用例2

無理やりOpenCVで使ってみる.BRISKで特徴点抽出し,オリエンテーションの向きによって表示する際の色を変えている.

#include <opencv2/opencv.hpp>
#include <cpplinq.hpp>

void main()
{
	using namespace cpplinq;

	auto image = cv::imread("Penguins.jpg");

	auto detector = cv::FeatureDetector::create("BRISK");
	std::vector<cv::KeyPoint> keyPoints;
	detector->detect(image, keyPoints);
	auto key1 = from(keyPoints)
		>> where([](cv::KeyPoint k) { return 0 <= k.angle && k.angle < 90;})
		>> to_vector();
	auto key2 = from(keyPoints)
		>> where([](cv::KeyPoint k) { return 90 <= k.angle && k.angle < 180;})
		>> to_vector();
	auto key3 = from(keyPoints)
		>> where([](cv::KeyPoint k) { return 180 <= k.angle && k.angle < 270;})
		>> to_vector();
	auto key4 = from(keyPoints)
		>> where([](cv::KeyPoint k) { return 270 <= k.angle && k.angle < 360;})
		>> to_vector();

	cv::drawKeypoints(image, key1, image, cv::Scalar(255,0,0), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	cv::drawKeypoints(image, key2, image, cv::Scalar(0,255,0), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	cv::drawKeypoints(image, key3, image, cv::Scalar(0,0,255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	cv::drawKeypoints(image, key4, image, cv::Scalar(255,255,0), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
	cv::imshow("Key Point", image);
	while(cv::waitKey(1) == -1);
}

f:id:whoopsidaisies:20140117010914p:plain