C++11 std::bind | std::function

48223 단어 C++11

std::function 모방 함수 대상


std:::function은 함수 대상을 설명하는 데 사용됩니다. 다시 말하면 함수 바늘, Lambda 표현식, 함수 이름과 같은 것입니다.
std::bind는 하나의 함수 대상을 다른 함수 대상으로 묶는 것입니다. std::bind의 반환값 형식은 std::function입니다.
헤더 파일#include 네임스페이스std, std::placeholdersbind 사용 시 주의사항: ①bind의 첫 번째 매개 변수는 주소 기호를 추가해야 합니다 & ②usingnamespacestd::placeholders를 추가해야 합니다. 그렇지 않으면 자리 표시자를 찾을 수 없습니다.
코드는 가장 좋은 선생님입니다. 두 말 없이 std::bind,std::function에서 사용하는 코드를 보십시오.
void showAll(int a, double b, const std::string& c)
{
     
	std::cout << a << "; " << b << "; " << c << std::endl;
}
void test()
{
     
	using namespace std::placeholders;

	std::function<void(int, double)> output = 
				std::bind(&showAll, _1, _2, "Kobe");
	output(1, 2);
}

코드를 보면 다음과 같은 규칙을 뚜렷하게 볼 수 있다. ①bind에서 자리를 차지하는 문자의 개수=호출할 때 전달되는 실삼의 개수=function<>에서 매개 변수 유형의 개수②std::bind는 함수 대상을 적합하게 배합하는 데 사용되며, std::function 유형으로 배합된다.

std::bind 귀속기


(1) 우선, std::bind도 함수 템플릿이고 반환값은 모방 함수이며 호출 대상입니다.그것의 작용은bind1st와bind2st와 유사하며 이 두 함수의 강화판이다.그러나 유연성을 크게 높여 bind1st와bind2nd를 완전히 대체할 수 있다.(2)bind의 역할은 주로 std::function ( )으로 바꾸는 것이고 주로 두 가지 측면에 나타난다.① 다원 과 그 매개 변수를 하나로 묶는다 .② 다원(설정된 매개 변수 개수는 n)의 를 일원 또는(n-1)원의 로 바꾸면 일부 매개 변수만 귀속된다.(3)std::bind가 귀속할 수 있는 대상 (bind의 반환값은 모방함수 주의) ① 、 √ static √ static ( :_1 ) / - STL 、std::function √ ⑤ 클래스의 데이터 구성원 (주의:_1은 특정한 대상의 주소여야 함)
다음은 코드를 통해 사용 방법을 하나하나 보여 줍니다. ① 、 √
static void show(const std::string& a, const std::string& b, const std::string& c)
{
     
	std::cout << a << "; " << b << "; " << c << std::endl;
}

int main()
{
     
	using namespace std::placeholders; //  std::placeholders, 

	auto x = bind(&show, _1, _2, _3);
	auto y = bind(&show, _3, _1, _2);
	auto z = bind(&show, "hello", _2, _1);

	auto xx = bind(&show, _3, _3, _3);

	x("one", "two", "three");  // one; two; three
	y("one", "two", "three");  // three; one; two
	z("one", "two");           // hello; two; one

	xx("one", "two", "three"); // three; three; three
}

static √류의static 구성원 함수는 클래스 대상에 속하지 않고 전체 클래스에 속하며 static 구성원 함수에 은연중에 포함되지 않은 첫번째this 매개 변수 결론: ①에 비해 클래스의static 구성원 함수bind를 추가할 때 작용역만 추가하면A:, 다른 것은 모두 같다
class A{
     
public:
	static void show(const std::string& a, const std::string& b, const std::string& c)
	{
     
		std::cout << a << "; " << b << "; " << c << std::endl;
	}
};

int main()
{
     
	using namespace std::placeholders; //  std::placeholders, 

	auto x = bind(&A::show, _1, _2, _3);
	auto y = bind(&A::show, _3, _1, _2);
	auto z = bind(&A::show, "hello", _2, _1);

	auto xx = bind(&A::show, _3, _3, _3);

	x("one", "two", "three"); // one; two; three
	y("one", "two", "three"); // three; one; two
	z("one", "two");          // hello; two; one

	xx("one", "two", "three");// three; three; three

	return 0;
}

static ( :_1 )
클래스의 비스타틱 구성원 함수는 클래스 대상에 속한다. 첫 번째 매개 변수는 은연중에 포함된다. 즉, 자신을 가리키는 바늘this 결론이다. 클래스의 비스타틱 구성원 함수bind에 대해 작용역을 추가해야 할 때 A::를 제외하고 클래스 대상 매개 변수를 하나 더 추가해야 한다.
class A{
     
public:
	void show(const std::string& a, const std::string& b, const std::string& c)
	{
     
		std::cout << a << "; " << b << "; " << c << std::endl;
	}
};

int main()
{
     
	using namespace std::placeholders; //  std::placeholders, 

	A aa;
	auto x = bind(&A::show, aa, _1, _2, _3);  // 
	auto y = bind(&A::show, aa, _3, _1, _2);
	auto z = bind(&A::show, aa, "hello", _2, _1);

	auto xx = bind(&A::show, aa, _3, _3, _3);

	x("one", "two", "three"); // one; two; three
	y("one", "two", "three"); // three; one; two
	z("one", "two");          // hello; two; one

	xx("one", "two", "three");// three; three; three

	return 0;
}

/ - STL 、std::function √
#include 
#include 
#include    //for count_if
#include   // for std::bind

using namespace std;
using namespace std::placeholders;

int main()
{
     
	vector<int> v{
      15, 37, 94, 50, 73, 58, 28, 98 };

	// bind2nd less() 2 50
	int n = count_if(v.begin(), v.end(), not1(bind2nd(less<int>(), 50)));
	cout << "n = " << n << endl; //5( 50 )

	// bind less() 2 50
	cout << count_if(v.begin(), v.end(), bind(less<int>(), _1, 50)) << endl; //3

	// bind 
	// (50,73] 
	//            logical_and- 
	auto f = bind(logical_and<bool>(), bind(greater<int>(), _1, 50), bind(less_equal<int>(), _1, 73));
	cout << count_if(v.begin(), v.end(), f) << endl; //2

	return 0;
}

예제 코드 1

#include 
#include 
using namespace std;
using namespace std::placeholders;

class Test{
     
public:
	typedef std::function<void(int, int)> pFUNC; // 

	Test() :x_(0), y_(0){
     }
	Test(int x, int y, pFUNC pfunc) :x_(x), y_(y), pfunc_(pfunc){
     }
	void run(){
     
		pfunc_(x_, y_);
	}

	void showAll03(int x, int y, int z, int m, int n)
	{
     
		printf("%d,%d,%d,%d,%d
"
, x, y, z, m, n); } private: int x_, y_; pFUNC pfunc_; }; void showAll01(int x, int y, int z){ printf("%d,%d,%d
"
, x, y, z); } void showAll02(int x, int y) { printf("%d,%d
"
, x, y); } int main(){ int i, j; cout << " i j :"; cin >> i >> j; Test aa(i, j, std::bind(showAll01, 10, _1, _2)); // showAll , CallBack aa.run(); Test bb(i, j, std::bind(showAll02, _1, _2)); bb.run(); Test dd; Test cc(i, j, std::bind(&Test::showAll03, &dd, 100, 200, _1, 300, _2)); cc.run(); }

예제 코드 2


본 사례는 대상을 대상으로 하는 프로그래밍 사상을 사용하는 것이 아니라 인터페이스를 바탕으로 하는 디자인 사상을 사용한다.
펭귄은 수영도 할 수 있고 달릴 수도 있고 참새는 날 수 있다. 이때 펭귄처럼 수영도 할 수 있고 달릴 수도 있고 참새처럼 날 수도 있다.만약에 다계승(펭귄, 참새 계승)을 사용한다면 결합이 비교적 밀접하다. std::bind,std::function을 사용하면 계승을 피할 수 있고 인터페이스를 바탕으로 하는 디자인 사상이다.
새 클래스 Foo에서 ① std::function 구성원 변수 추가 ② Foo 구조 함수에서 구성원 변수에 값 부여 ③main 함수에서 구조 함수를 호출하여 Foo 대상을 만들고 bind에 사용
	Foo m_foo(
		bind(&Penguin::run, &peg),
		bind(&Penguin::swim, &peg),
		bind(&Sparrow::fly, &spr)
	);

모든 코드:
#include 
#include 
using namespace std;
using namespace std::placeholders;

// , 
class Penguin
{
     
public:
	void run(){
      cout << "run..." << endl; }
	void swim(){
      cout << "swim..." << endl; }
};

// 
class Sparrow
{
     
public:
	void fly(){
      cout << "fly..." << endl; }
};

//  run, fly class
class Foo{
     
public:
	typedef std::function<void()> RUN;
	typedef std::function<void()> SWIM;
	typedef std::function<void()> FLY;

	Foo(RUN run, SWIM swim, FLY fly) :
		m_run(run), m_swim(swim), m_fly(fly)
	{
      }


	void run()
	{
     
		m_run(); // 
	}
	void swim()
	{
     
		m_swim();
	}
	void fly()
	{
     
		m_fly();
	}
private:
	RUN		m_run;
	SWIM	m_swim;
	FLY		m_fly;
};
int main()
{
     
	Penguin peg;
	Sparrow spr;

	Foo m_foo(
		bind(&Penguin::run, &peg),
		bind(&Penguin::swim, &peg),
		bind(&Sparrow::fly, &spr)
	);

	m_foo.run();
	m_foo.swim();
	m_foo.fly();

	return 0;
}

좋은 웹페이지 즐겨찾기