-->

C/C++

他言語であるラムダ式だ。
書き方は、

[キャプチャ](引数リスト) ->戻り値型 { }

で、この関数の型は、

std::function<戻り値型 (引数型リスト)>

になる。あと、functionalヘッダをincludeする。

足し算するラムダを書いてみる。

std::function<int(int, int)> plus = [](int a, int b) -> int {
	return a + b;
};

std::cout << plus(1, 1) << std::endl; // "2"を表示

型推論使って、すっきりに。

auto plus = [](int a, int b) -> int {
	return a + b;
};

std::cout << plus(1, 1) << std::endl; // "2"を表示

キャプチャ
いわゆるクロージャを作るのに必要。ラムダ式を宣言したスコープ内のローカル変数をラムダ式内で使用することだ。
まー、書いてみればわかる。

#include "stdafx.h"
#include <iostream>
#include <functional>

std::function<int()> getTestFunc() {
	int hoge = 20;
	return[=]() { return hoge; };
}

int _tmain(int argc, _TCHAR* argv[])
{
	auto test = getTestFunc();

	std::cout << test() << std::endl; // "20"を表示

	return 0;
}

=と書くと、ラムダ式が宣言された段階での値がコピーされる。(コピーキャプチャ)
&と書くと、参照になる。(参照キャプチャ)

#include "stdafx.h"
#include <iostream>
#include <functional>

std::function<int()> getTestFunc() {
	int hoge = 20;
	return[&]() { return hoge; };
}

int _tmain(int argc, _TCHAR* argv[])
{
	auto test = getTestFunc();
	
	std::cout << test() << std::endl; // 変な値が表示される。
	
	return 0;
}

参照だと、getTestFuncからリターンした段階でローカル変数のhogeは無くなっているので変なところを参照していることになり、変な値が表示される。やっちゃ、いけない。考えて使おー。

変数を個別にコピーキャプチャする場合は、[]内に[hoge1, hoge2]のように変数名をカンマ区切りで書く。参照キャプチャする場合は、[&hoge1, &hoge2]のように書く。[hoge1, &hoge2]のようにコピーキャプチャの変数と参照キャプチャの変数も混ぜれる。hoge1は参照キャプチャでそれ以外はコピーキャプチャの場合は[=,&hoge1]と書く。

JavaScriptのクロージャの説明でよくあるカウントアップする関数を返すのを書いてみる。

std::function<int()> getCounter()  {
	int counter = 0;
	return[counter]() { return ++counter; };
}

けど、エラーになる。キャプチャした変数が変更できないみたいだ。
変更するには、ラムダ式mutableをつける。

#include "stdafx.h"
#include <iostream>
#include <functional>

std::function<int()> getCounter()  {
	int counter = 0;
	return[counter]() mutable { return ++counter; };
}

int _tmain(int argc, _TCHAR* argv[])
{
	auto countUp = getCounter();
	
	std::cout << countUp() << std::endl; // "1"を表示
	std::cout << countUp() << std::endl; // "2"を表示
	std::cout << countUp() << std::endl; // "3"を表示
	std::cout << countUp() << std::endl; // "4"を表示
	
	return 0;
}

このエントリーをはてなブックマークに追加

C++11で他の言語でよくある型推論が追加された。型名の代わりにautoを使って変数を宣言する。

#include "stdafx.h"
#include <typeinfo>
#include <iostream>

class object {
};

int _tmain(int argc, _TCHAR* argv[])
{
	auto hoge1 = 2;				// int型になる
	auto hoge2 = "hogehoge";	// const char *型になる
	auto hoge3 = new object();	// object *型になる
	auto hoge4 = 3.14;			// double型になる


	std::cout << typeid(hoge1).name() << std::endl;
	std::cout << typeid(hoge2).name() << std::endl;
	std::cout << typeid(hoge3).name() << std::endl;
	std::cout << typeid(hoge4).name() << std::endl;

	return 0;
}

VisualStdio 2013で試した。
gccでコンパイルする場合は、ちょっといじって(^^;)、-std=c++11とオプションを付けてコンパイルする必要がある。


このエントリーをはてなブックマークに追加

別のブログで公開してたものです。
一部をこっちのブログに移行しようと手動で(^^;)移行したものです。

NDKでメディアン部分をCで作ってみた。

MedianTestAndroid2.1.zip

Nexus7(2012)で測ってみた結果がこんな感じ。

001.jpg:1.2672秒
002.jpg:1.2042秒
003.jpg:1.1373秒
004.jpg:1.1525秒
005.jpg:1.1444秒
006.jpg:1.1462999999999999秒
007.jpg:1.1276秒
008.jpg:1.1260999999999999秒
009.jpg:1.1236000000000002秒
010.jpg:1.1218秒

Javaが6.5秒ぐらいだったんで、むっちゃ速い!てか、Dalvik遅すぎ。





このエントリーをはてなブックマークに追加

↑このページのトップヘ