반응형

[C++11] std::bind, std::placeholders 사용법

 

std::bind란?

함수 템플릿 바인드는 함수에 대한 전달 호출 wrapper를 생성합니다. 전달 인자를 설정할 수 있는 함수 포인터라고 보시면 됩니다. 
 

std::bind 사용 방법

template< class F, class... Args >
/*unspecified*/ std::bind( F&& f, Args&&... args );
 
f - 일부 인수에 바인딩되는 호출 가능한 객체입니다.(함수 객체, 함수에 대한 포인터, 함수에 대한 참조, 멤버 함수에 대한 포인터 또는 데이터 멤버에 대한 포인터)

args - 바인드할 전달인자 목록입니다. 바인딩되지 않은 인수는 namespace std::placeholders의 자리 표시자 _1, _2, _3...으로 대체될 수 있습니다. 
 

std::placeholder 이란?

보통 std::bind와 같이 많이 쓰이며, 함수의 인자를 받을 수 있도록 해줍니다. 
std::placeholders::_1, std::placeholders::_2, ..., std::placeholders::_N 형식으로 사용됩니다. 
 

std::bind, std::placeholder의 header 파일

#include <functional>
 

std::bind, std::placeholder의 사용 예제

#include <iostream>
#include <functional>


void add(int n1, int n2) {
    std::cout << "n1 = " << n1 << ", n2 = " <<  n2 << std::endl;
    std::cout << "add = " << n1 + n2 << std::endl;
}

void sub(int n1, int n2) {
    std::cout << "n1 = " << n1 << ", n2 = " << n2 << std::endl;
    std::cout << "sub = " << n1 - n2 << std::endl;
}

int main() {
    auto f1 = std::bind(add, 100, std::placeholders::_1);
    f1(5); // add(100, 5) 형식으로 호출됩니다.

    auto f2 = std::bind(sub, std::placeholders::_1, std::placeholders::_2);
    f2(10, 7); // sub(10, 7) 형식으로 호출됩니다.

    return 0;
}

 

 
 
 
 

참조

https://en.cppreference.com/w/cpp/utility/functional/bind

std::bind - cppreference.com

(1) template< class F, class... Args > /*unspecified*/ bind( F&& f, Args&&... args ); (since C++11) (until C++20) template< class F, class... Args > constexpr /*unspecified*/ bind( F&& f, Args&&... args ); (since C++20) (2) template< class R, class F, clas

en.cppreference.com

https://en.cppreference.com/w/cpp/utility/functional/placeholders

std::placeholders::_1, std::placeholders::_2, ..., std::placeholders::_N - cppreference.com

/*see below*/ _1; /*see below*/ _2; . . /*see below*/ _N; The std::placeholders namespace contains the placeholder objects [_1, ..., _N] where N is an implementation defined maximum number. When used as an argument in a std::bind expression, the placeholde

en.cppreference.com

 

반응형
반응형

C++ Boost 라이브러리 설치 및 Visual studio 설정 (윈도우용)

 

boost 라이브러리를 설치하고, Visual studio에서 이 라이브러리를 적용해 빌드하는 것을 다루어 보겠습니다. 

 

1. boost 라이브러리 다운로드

우선 아래 링크에 접속합니다.

https://www.boost.org/

 

Boost C++ Libraries

Welcome to Boost.org! Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work well with the C++ Standard Library. Boost libraries are intended to be widely useful, and usable across a broad spectrum of applications

www.boost.org

접속해서 최신 Release 버전을 클릭하여 아래 페이지가 나오면, windows 용 압축파일을 다운로드 합니다.

압축파일의 용량은 100MB 조금 되지 않습니다.

2. boost 라이브러리 설치 및 빌드

다운로드가 끝났으면, 압축을 풀고 bootstrap.bat을 실행시킵니다. 

실행을 시키면 아래와 같이 코드를 생성하고 컴파일을 합니다. 

 

위 과정이 끝나면 b2.exe 파일이 생성됩니다. 

이 파일을 실행하여 boost 라이브러리를 빌드합니다. 

빌드되는데 시간이 조금 오래 걸립니다. 

빌드가 완료되면  include 디렉토리와 lib 디렉토리가 출력됩니다 .

- include : E:\Project_Cplus\boost_1_80_0\boost_1_80_0

- lib : E:\Project_Cplus\boost_1_80_0\boost_1_80_0\stage\lib

3. Visual Studio에서 boost 라이브러리 적용

생성된 프로젝트에서 속성창을 open합니다

아래 2 경로를 설정해야 합니다. 

- include : E:\Project_Cplus\boost_1_80_0\boost_1_80_0

- lib : E:\Project_Cplus\boost_1_80_0\boost_1_80_0\stage\lib

 

먼저 include는 C/C++ 일반의 '추가 포함 디렉터리'에서 추가합니다. 

lib는 링커의 일반에서 '추가 라이브러리 디렉터리'를 설정하여 줍니다. 

 

4. boost 라이브러리를 이용한 sample 프로그램 빌드 및 실행

Thread를 사용하는 간단한 프로그램을 작성하여 빌드해봅니다. 

#include <stdio.h>
#include <iostream>
#include <crtdbg.h>

#include <boost/asio/thread_pool.hpp>
#include <boost/asio/post.hpp>

using namespace std;
using namespace this_thread;
using namespace chrono;


void threadTest()
{
    // 반복문을 돌면서 콘솔에 값을 출력한다.
    for (int i = 0; i < 4; i++)
    {
        cout << i << endl;
        sleep_for(microseconds(1));
    }
}

int main()
{
    boost::asio::thread_pool* pool = new boost::asio::thread_pool(1);
    /* 쓰레드 실행 */
    post(*pool, threadTest);
    post(*pool, threadTest);
    post(*pool, threadTest);

    
    pool->join(); // pool 내의 모든 쓰레드가 종료할 때까지 기다린다.
    delete pool; // 메모리 해제
    _CrtDumpMemoryLeaks(); // 메모리 릭체크 함수.
    return 0;
}

그러면 아래와 같이 빌드되고, 실행되는 것을 볼 수 있습니다.

반응형
반응형

비교 표현식 -gt -lt -ge -le -eq -ne

 

GT : greater

LT : Little

EQ : Equal

구분 표현식 비교
크다 a -gt b a > b
크거나 같다 a -ge b a >= b
작다 a -lt b a < b
작거나 같다 a -le b a <= b
같다 a -eq b a == b
같지 않다 a -ne b a != b

 

반응형
반응형

[C++11] std::thread 사용법 (함수, 클래스)

 

std::thread란 

클래스 스레드는 단일 실행 스레드를 나타냅니다. 스레드를 사용하면 여러 기능을 동시에 실행할 수 있습니다. 

std::thread는 C++11에서 표준으로 되었습니다. 

 

 

std::thread Header 파일

#include <thread>

 

 

thread 생성 방법

thread 생성은 보통 아래 방법이 있습니다. 

lambda를 이용한 방법도 있는데, 나중에 한번 알아보도록 하겠습니다. 

1. 함수를 이용한 생성 => std::thread 변수(함수명, 전달인자)

2. Class 멤버 함수를 이용한 생성 => std::thread  변수(class명::thread 수행할 함수, class 생성자, 전달 인자);

3. Class Static 함수를 이용한 생성 => std::thread  변수(class명::thread 수행할 함수, 전달 인자);

 

 

 

thread 생성 예제

thread가 작업 중인데, main 함수에서 return 0; 으로 종료하려고 할 때, 비정상적으로 종료될 수 있습니다.

이를 방지하고자, thread의 join 함수를 사용하여, main thread는 자식 thread의 작업을 기다리고, thread의 작업이 끝나면, main thread는 실행을 재개합니다. 

thread를 실행시킬 때, 함수의 전달인자를 넣을 수도 있고, 넣지 않아도 됩니다.

 

1. 함수를 이용한 생성

1부터 1000까지 더하는 작업을 하는 thread를 만들어 보겠습니다. 

#include <iostream>
#include <string>
#include <thread>


void sum_thread()
{
    int sum = 0;
    for (int i = 1; i <= 1000; i++)
        sum += i;
    std::cout << "sum_thread() : " << sum << std::endl;
}

int main()
{
    std::thread sum(sum_thread);

    std::cout << "main() : start" << std::endl;
    sum.join();
    std::cout << "main() : finish" << std::endl;
}

위 코드를 실행해보면 아래와 같이 출력합니다. 

thread의 작업이 끝날때까지 기다리기위해 join 함수를 사용하였습니다. 

join 함수가 끝나고 main thread에서 실행을 재개합니다.

 

2. Class 멤버 함수를 이용한 생성 & 3. Class Static 함수를 이용한 생성

 

#include <iostream>
#include <string>
#include <thread>


class SUM {
public :
    static void sum_static(int num) {
        int sum = 0;
        for (int i = num; i <= 100; i++)
            sum += i;
        std::cout << "sum_static() : " << sum << std::endl;
    }
    void sum_func(int num) {
        int sum = 0;
        for (int i = num; i <= 1000; i++)
            sum += i;
        std::cout << "sum_func() : " << sum << std::endl;
    }
};

int main()
{

    // 2. Class의 멤버 함수를 사용한 Thread 생성
    std::thread thread1(&SUM::sum_func, SUM(), 10);


    // 3. Class의 Static 함수를 사용한 Thread 생성
    std::thread thread2(SUM::sum_static, 10);




    std::cout << "main() : start" << std::endl;
    thread1.join();
    thread2.join();
    std::cout << "main() : finish" << std::endl;
}

thread가 병렬로 작업을 수행해서 출력이 섞여서 출력이 됩니다. 

나중에는 이러한 것들을 순차적으로 수행할 수 있도록 해보도록 하겠습니다.

반응형

+ Recent posts