Modern C++ - std::function

진경천·2024년 3월 20일
0

C++

목록 보기
88/90

std::function의 기본형태

Callable들을 객체의 형태로 보관할 수 있는 클래스이다.
std::function<[return type]([parameter type])> func

위와 같은 형태로 func이라는 객체에 Callable을 보관할 수 있다.

#include <iostream>
#include <functional>

using std::cout;
using std::endl;

template<typename T>
void foo() {
	cout << typeid(T).name() << endl;
}

int func(float) {
	return 1.1f;
}

struct Func {
	static int func(float value) {
		return value;
	}
};

int main() {
	foo<int(float)>();
    
	std::function<int(float)> f0 = func;
	std::function<int(float)> f1 = [](float value) {return value; };
    
	std::function<int(float)> f2 = Func::func;
	cout << f0(1.1f) << endl;
	cout << f1(2.1f) << endl;
	cout << f2(3.1f) << endl;
    
    int(Func:: * f)(float) const = &Func::func;
	cout << (Func().*f)(2) << endl;

	std::function<int(const Func&, float)> f0 = &Func::func;
	cout << f0(Func(), 5.1f) << endl;
}

실행 결과

int __cdecl(float)
1
2
3
2
5

<int(float)>은 함수 호출 규약에 따라 float을 인자로 받아 int를 반환하는 것을 출력 결과에서 확인할 수 있으며

std::function은 함수 뿐 아니라 클래스의 객체, 람다 또한 보관할 수 있다는 것을 확인할 수 있다.

#include <iostream>
#include <functional>

using std::cout;
using std::endl;

struct Func {
	int func(float value) const {
		return value;
	}
};

int main() {
	int(Func:: * f)(float) const = &Func::func;
	cout << (Func().*f)(2) << endl;

	std::function<int(const Func&, float)> f0 = &Func::func;
	cout << f0(Func(), 5.1f) << endl;
}

실행 결과

2
5

함수 포인터 형태와 클래스를 인자로 받을 수도 있다.

std::bind

std::bind([함수], [인자1], [인자2], ..., [인자n])

함수 객체 생성 시에 인자를 지정해준다.

std::placeholder

ex) auto f = std::bind(func, 2, std::placeholder::_1)
func이라는 함수를 보관하는 f라는 함수 객체를 생성하며
첫번째 인자는 2로 지정해주며 새롭게 만들어진 f의 1번째 인자를 2번째 인자로 받겠다는 의미이다.

예제

#include <iostream>
#include <functional>

using std::cout;
using std::endl;

void func(int n1, int n2, int n3) {
	cout << n1 << endl;
	cout << n2 << endl;
	cout << n3 << endl;
}

int main() {
	std::bind(func, std::placeholders::_3, std::placeholders::_1, std::placeholders::_2)
		(1, 2, 3);
}

실행 결과

3
1
2

3번째 인자인 3func의 첫번째 인자, 1이 두번째 인자, 2가 3번째 인자로 들어간 것을 확인할 수 있다.

#include <iostream>
#include <functional>

using std::cout;
using std::endl;

struct Func {
	int func(float value) const {
		return value;
	}
};

int main() {
	int(Func:: * f)(float) const = &Func::func;
	cout << (Func().*f)(2) << endl;

	std::function<int(const Func&, float)> f0 = &Func::func;
	cout << f0(Func(), 5.1f) << endl;

	std::function<int(float)> f1 = std::bind(&Func::func, Func(), std::placeholders::_1);
	cout << f1(10.1f) << endl;

	std::function<int()> f2 = std::bind(f1, 12.f);
	cout << f2() << endl;

	std::function<int(const Func&)> f3 = std::bind(f0, std::placeholders::_1, 13.f);
}

실행 결과

2
5
10
12

profile
어중이떠중이

0개의 댓글