[](const int& i) -> void {cout << "Hello, World" << endl;} (1234);
std::function<void()> printHello = []() { std::cout << "Hello, World\n"; };
printHello();
auto boundFunc = std::bind(printHello);
boundFunc();
placeholder
Object instance; auto f = std::bind(&Object::hello, &instance, std::placeholders::_1);
- 파라미터의 개수를 딱 잡아준다.
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// for_each와 람다를 사용하여 벡터의 각 요소를 출력
std::for_each(vec.begin(), vec.end(), [](int i) {
std::cout << i << ' ';
});
std::cout << std::endl;
return 0;
}
#include <tuple>
#include <iostream>
std::tuple<int, double, std::string> getValues() {
return std::make_tuple(1, 2.3, "Hello");
}
int main() {
auto [i, d, s] = getValues();
std::cout << i << ", " << d << ", " << s << std::endl;
return 0;
}
멀티쓰레딩
프로세스: 실행 중인 프로그램의 인스턴스
쓰레드: 프로세스 내에서 실행되는 흐름의 단위
멀티쓰레딩: 하나의 프로세스가 여러 쓰레드를 동시에 실행하여 여러 작업을 동시에 처리할 수 있는 기법
멀티쓰래딩은 직접 구현해야한다.
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <mutex>
using namespace std;
int main(){
const int num_pro = std::thread::hardware_concurrency(); // 컴퓨터의 코어 갯수 확인
cout << std::this_thread::get_id() << endl; // 해당 작업의 쓰레드의 아이디
std::thead t1 = std::thread([]() {while (true) {}});
t1.join(); // t1이 끝날 때 까지 기다림
}
레이스 컨디션: 두 개 이상의 스레드가 동시에 공유 자원에 접근하려고 할 때 발생하는 문제
atomic: 여러 스레드에서 동시에 접근할 수 있는 변수를 안전하게 사용
scoped_lock: 블록 범위 내에서 뮤텍스를 안전하게 잠그고, 범위를 벗어날 때 자동으로 뮤텍스를 해제
#include <iostream>
#include <atomic>
#include <thread>
#include <mutex>
std::atomic<int> counter(0);
std::mutex mtx;
void incrementCounter() {
counter++;
std::scoped_lock lock(mtx);
// 여기서 안전하게 공유 자원에 접근
}
int main() {
std::thread t1(incrementCounter);
std::thread t2(incrementCounter);
t1.join();
t2.join();
std::cout << counter << std::endl;
return 0;
}
비동기 프로그래밍이란?
여러 작업을 동시에 실행하면서, 현재 스레드의 실행을 차단하지 않고 결과를 기다리는 프로그래밍 방식. 효율적으로 시스템 리소스를 활용하고 애플리케이션의 응답성을 향상시킬 수 있음.
#include <iostream>
#include <future>
#include <thread>
using namespace std;
int main() {
// mutli-threading
{
int result;
// 별도의 스레드를 생성하여 람다 함수를 실행
std::thread t([&] {result = 1 + 2;});
t.join(); // t 스레드가 종료될 때까지 기다림
cout << result << endl; // 결과 출력
}
//task-based parallelism
{
// std::async를 사용하여 비동기적으로 람다 함수를 실행
auto fut = std::async([] {return 1 + 2; });
cout << fut.get() << endl; // 결과가 준비될 때까지 기다린 후 결과 출력
}
}
//future and promise
{
std::promise<int> prom;
auto fut = prom.get_future();
auto t = std::thread([](std::promise<int>&& prom)
{
prom.set_value(1+2);
}, stdd::moce(prom));
cout << fut.get() endl;
t.join();
}
teplate<typename T>
void func_wrapper(T&& t){
func(std::forward<T>(t));
}
decltype: auto가 컴파일타임에서 타입을 추론하기에 역부족일 때 주로 사용
새로운 데이터 타입을 정의
typedef decltype(A) B or declytype(A) B = A;
decltype은 *, const 등등을 그대로 보존
반환 가능 , 함수 이름 뒤에 '-> 리턴 타입'
decltype((A))은 래퍼런스 & 를 타입에 덧 붙여줌
A가 연산 식이라면
A의 연산 결과가 변수라면 &를 붙임
연산 결과가 R-value라면 &를 붙이지 않는다.
A 연산식에 사용된 두 변수가 같은 데이터 타입이라면 결과 데이터 타입에 &을 타입에 덧붙여 준다.
A 연산식에 사용된 두 변수가 다른 데이터 타입이라면 결과 데이터 타입에 &을 타입에 덧붙여주지 않는다.
std::remove_reference를 사용하여 &를 제거할 수 있따.
런타입이 아닌 컴파일 타임에 결정된다.