728x90
반응형

Program Language/C & C++ 112

[C++] emplace_back

std::vector에서 push_back 함수는 '객체'를 집어넣는 형식으로 객체가 없이 삽입하려면 '임시 객체'가 있어야 한다. #include #include #include using namespace std; struct item_t { item_t() : aa("default"), vv(0) {} item_t(string a, int v) { aa = a; vv = v; } string aa; int vv; }; int main() { vector items; item_t item = {}; // 기본 생성자 items.push_back(item_t("abc", 3)); items.push_back(std::move(item)); cout

[C++] 윈도우즈에서 텍스트로 함수 호출

남겨진 코드를 쫓다 보니 함수형 프로그래밍의 초입까지 도착한 것 같다. 우선 가장 간단하게 함수 이름으로 함수를 실행시키는 코드가 필요했다. 이런저런 복잡한 코드가 많았는데 Windows와 gcc를 사용하는 os와의 차이는 조금 있는 것 같다. 나는 우선 windows를 사용하니 #include typedef void(&u_func)(char*); void hello(char* name) { printf("hello %s !!\n", name); } int main() { HMODULE module = GetModuleHandle(NULL); FARPROC proc = GetProcAddress(module, "hello"); hello("Tom"); return 0; } 이렇게 간단하게 구현해 봤다. ..

error C2558 : no copy constructor available or copy constructor is declared 'explicit'

클래스나 구조체를 vector의 push_back을 이용하여 넣으려고 하니 C2558 에러가 발생한다. 생성자에서 복사가 불가능하거나 복사 생성자에 explicit이 선언되어 있다는 것이다. 여기저기 검색하다 보니 const를 선언하지 않아서 발생한 에러였다. typedef struct PSOPACK_T { PSOPACK_T(PSOPACK_T& other) { func = move(other.func); } } typedef struct PSOPACK_T { PSOPACK_T(const PSOPACK_T& other) { func = move(other.func); } }

[C++] std::async

std::async는 std::task 클래스 기반으로 만들어진 클래스로 thread를 만들 때 사용한다. std::async는 std::thread와 달리 내부적으로 thread pool을 만들어 thread를 관리하며 std::thread보다 안정적이며 프로그래머가 사용하기 편하다. std::async는 반환 값을 std::future로 받는다. #include #include using namespace std; void print(char id) { for (int i = 0; i < 10; i++) { printf("thread no : %c , Count : %d \n", id, i); } } int main() { std::future a = std::async(std::launch::asy..

[C++] values

C에서의 Rvalue, Lvalue는 좌측 값은 대입(assignment) 시에 왼쪽 혹은 오른쪽에 오는 식(expression)이고, 우측 값은 대입 시에 오직 오른쪽에만 오는 식이다.라고 정의하고 있지만 C++에서는 다음과 같이 정의하고 있다. 좌측 값은 어떠한 메모리 위치를 가리키는데, & 연산자를 통해 그 위치를 참조할 수 있다. 우측 값은 좌측 값이 아닌 값들이다. C++11부터는 prvalue, xvalue, glvalue가 추가되었다. C++11에서는 이러한 value들을 다음과 같이 나누었다. lvalue : identity를 가지면서 move 될 수 없는 표현식 xvalue : identity를 가지면서 move 될 수 있는 표현식 prvalue : identity를 가지지 않고 있으면서..

[C++] std::move

template constexpr typename std::remove_reference::type&& move(T&& t) noexcept; std::move는 C++11에 도입된 개념으로 t가 가지고 있는 자원을 다른 객체에게 효율적으로 전달하는 것을 의미한다. std::move는 이동을 수행하지는 않는다. 이동될 수 있음을 알려주는 역할만 한다. std::move 된 객체를 함수에 전달한다면, 우측 값 레퍼런스를 인자로 받는 함수 (이동 생성자, 이동 대입 연산자, push_back 등)가 오버 로딩되어서 선택된다. 참고로 우측 값 레퍼런스 자체는 lvalue이기 대문에, 이동 생성자나 이동 대입 연산자 내부에서 std::move를 호출하는 경우가 많다. // 이동 생성자 A(A&& arg) : m..

[C++] thread_local

thread_local은 thread가 TLS(Thread Local Storage)를 지원하기 위해서 C++11부터 추가되었다. 기존에 TLS변수를 선언하기 위해서는 __declspec(thread)를 사용해야만 했다. 하지만 정식으로 thread_local가 도입됨으로 간편하게 사용할 수 있게 되었다. TLS(Thread Local Storage) : thread 별로 고유한 저장공간을 가질 수 있는 방법이다. 각각의 thread는 고유한 Stack을 가지기 때문에 Stack 변수(지역 변수)는 thread별로 고유하다. 그래서 각각의 thread가 같은 함수를 실행한다고 해도 그 함수에서 정의된 지역 변수는 실제로 서로 다른 메모리 공간에 위치한다는 의미다. 그러나 정적 변수와 전역 변수의 경우에는..

[C++] recursive_mutex

std::mutex의 lock()의 경우 lock을 호출한 함수에서 unlock을 호출하지 않고 또다시 lock을 호출하면 알 수 없는 동작을 하게 된다고 한다. 예를 들면 아래와 같다. class buffer { list queue; std::mutex mut; public: bool empty() { std::lock_guard lock(mut); return queue.empty(); } // 생략 int pop() throw(out_of_range) { std::lock_guard lock(mut); while (empty()) { // 생략 } int tmp = queue.front(); queue.pop_front(); return tmp; } }; buffer 클래스에서 pop() 함수를 호..

[C++] result_of

지정된 인수 유형을 사용하는 호출 가능 형식의 반환 형식을 결정한다. template struct result_of; // Causes a static assert template struct result_of; // Helper type template using result_of_t = typename result_of::type; Fn : 쿼리할 호출 가능 형식 ArgTypes : 쿼리 할 호출 가능 형식에 대한 인수 목록의 형식 #include #include struct S { double operator()(char, int&); float operator()(int) { return 1.0; } }; template typename std::result_of::type f(T& t) { st..

[C++] condition_variable

thread를 수행할 때 때로는 다른 thread의 작업을 기다려야 할 때가 있다. 이때 condition_varialbe을 사용하면 thread를 block 할 수 있다. block 조건은 timeout을 설정할 수 도 다른 thread를 통해 설정할 수도 있다. condition_variable은 다음과 같은 method를 제공한다. notify_one : 해당 조건 변수를 기다리고 있는 thread 중 한 개의 thread를 깨운다. notify_all : 해당 조건 변수를 기다리고 있는 모든 thread를 깨운다. thread는 상기 method 이외에 timeout에 의해서 깨어날 수도 있다. #include #include #include using namespace std; mutex g_m..

[C++] noexcept

C++11부터 throw()가 더 이상 사용되지 않고, noexcept 키워드가 추가되었다. noexcept 키워드는 operator의 형태로, 그리고 specifier의 형태로 제공된다. noexcept() 한정자는 모든 면에서 throw() 보다 강력하고, Stnadard library들을 사용함에 있어, noexcept 한정자는 성능 상의 추가 이득을 제공하기도 한다. noexcept(expression) noexcept 연산자는 컴파일 타임에 해당 표현식이 예외를 던지지 않는 표현식인지 체크하여 표현식이 아래의 경우 중 하나라도 포함한다면 false를 그렇지 않다면 true를 반환한다. 상수 표현식이 아닌 함수가 noexcept 키워드를 가지지 않을 경우 런타임 체크가 필요한 dynamic_cas..

[C++] atomic

std::atomic은 원자성을 보존해주기 위해 사용된다. 다시 말하자면 mutex 없이 두 개의 스레드가 동시에 접근해도 data race 문제가 발생하지 않는다. 또한 std::atomic을 기록하는 라인이 수행될 때는 이전에 나타난 라인들이 수행되어서는 안 된다. std::atomic은 복사와 이동 연산을 지원하지 않는다. 원자성을 보존해야 하기 때문이다. 다행히 복사하는 방법은 있다. atd::atomic y(x.load()); y.store(x.load()); mutex를 통한 전역 변수 동기화에서는 dead lock에 빠질 수 있다. 그래서 atomic을 이용하여 lock, unlock을 사용하지 않고 값을 증가시키거나 감소시킬 수 있는 기능이 C++11부터 제공되고 있다. atomic : a..

[C++] thread에서 return 값 받기 (promise/future)

C++11 이후에는 이 추가되었으며 future, promise를 통해서 값이나 예외를 저장할 수 있다. 생성하려는 Thread에 Promise를 매개변수로 전달해서 받아올 수 있다. 미래에(future) thread가 원하는 데이터를 돌려 주겠다고 약속(promise)하는 것이라고 할 수 있다. #include #include #include #include void ThreadFunc(std::promise& retVal) { retVal.set_value(1); } int main() { std::promise p; std::future f = p.get_future(); std::thread th1(ThreadFunc, std::ref(p)); th1.join(); std::cout

[C++] 명시적 링크 (Explcit Linking) 시 GetProcAddress NULL 반환

아래는 mdsn에서 제공하는 dynamic linking 예제이다. 평소에 아무 생각없이 잘 사용하다가 갑자기 GetProcAddress에서 계속해서 NULL이 Return 된다. ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); 함수이름도 매개변수 형식도 모두 맞지만 계속해서 NULL이 반환 되었다. 그래서 이것저것 테스트해 본결과 namespace 안에 있는 함수를 가져 오지 못하는 것이었다. 그럼, 함수 이름 앞에 네임스페이스::함수 이렇게 하면 동작할려나.. @_@ 왜 당연히 읽어 올거라고 생각한걸까.. 네임스페이스 안은 완전 다른 세상인데... // A simple program that uses LoadLibrary and // GetProcAd..

728x90
반응형