Advanced C++ 42

[Modern C++] (8) 다듬기

시퀀스 컨테이너 (vector/list/string/deque)와 연관 컨테이너 (map/set/unordered_map/set)에서 원소를 삽입하는 방법에 대하여 고려할 사항을 알아본다. 1. 이동이 저렴하고 항상 복사되는 복사 가능 매개변수에 대해서는 값 전달을 고려해라 Widget 인스턴스에 string 객체를 추가하는 addName 함수에 대하여 오른값과 왼값을 받는 중복 적재 버전 class Widget { private: std::vector names; public: // 왼값 참조를 받는 버전 void addName(const std::string& newName) { names.push_back(newName); } // 오른값 참조를 받는 버전 void addName(std::strin..

Advanced C++ 2021.05.04

[Modern C++] (7-2) 동시성 API

C++11부터 도입된 동시성 API관련 항목을 이어 공부한다. 4. 스레드 핸들 소멸자들의 다양한 행동 방식을 주의하라. std::thread, 미래 객체 std::future 모두 시스템 스레드에 대응되는 핸들이라고 할 수 있다. std::thread는 소멸자 호출시 바탕 스레드가 합류가능상태이면 프로그램이 종료되어버린다. 하지만 미래 객체는 암묵적 join/detach를 한 것처럼 프로그램이 종료되지는 않는다. 미래 객체는 스레드-미래 객체의 통신 채널의 끝 단자의 역할을 한다. 비동기적으로 실행하는 피호출자는 계산 결과를 통신 채널에 기록한다.(std::promise를 통해서) 호출자는 미래 객체를 통해 결과를 읽는다. 계산 결과가 저장되는 곳은? 피호출자에 담아둔다: std::promise가 피호..

Advanced C++ 2021.05.01

[Modern C++] (7-1) 동시성 API

C++11를 기점으로 도입된 동시성(Concurrency)을 언어와 표준 라이브러리에 도입하였다. 표준 라이브러리의 동시성 구성요소들 (과제, 미래, 스레드, 뮤 텍스, 조건 변수, 원자적 객체)에 대해 알아보도록 한다. 1. 스레드(Thread) 기반 프로그래밍보다 과제(Task) 기반 프로그래밍을 선호하라 스레드 기반 프로그래밍 이란 - 새로운 스레드를 실행하는 함수를 할당하여 생성하는 방식 int doAsyncWork(); std::thread t(doAsyncWork); 과제 기반 프로그래밍 auto fut = std::async(doAsyncWork); // fut은 future를 뜻한다. std::async에 전달된 doAsyncWork는 과제로 취급한다. 과제 기반 프로그래밍을 선호하는 이유..

Advanced C++ 2021.05.01

[Modern C++] (6) 람다 표현식

람다 표현식 Lambda - 보통 함수와 같은 의미를 지니는 표현식이다. - 클로저 Closure는 람다에 의해 만들어진 실행 시점의 객체이다. 갈무리 모드 Capture mode에 따라 갈무리된 자료의 복사본 혹은 참조를 가질 수 있다. - 클로저 클래스는 람다에 대해 컴파일러가 만든 고유한 클래스이다. 보통 STL 함수의 인수로 많이 사용된다. std::vector container; std::find_if(container.begin(), container.end(), [](int val) {return 0 < val && val < 10; }); 1. 기본 갈무리 모드를 피하라 기본 갈무리 모드 중 하나는 참조에 의한 갈무리 모드와 값에 의한 갈무리 모드가 있다. 두 모드에 내재된 위험성은 참조대..

Advanced C++ 2021.04.20

[Modern C++] (5-2) 오른값 참조, 이동 의미론, 완벽전달

이번 포스트에서는 보편 참조를 사용할 때 주의사항에 관해 정리해본다. 4. 보편 참조에 대한 중복적재(오버로딩)을 피해라 사람이름을 받아 현재 시간을 기록하고 그 이름을 전역 자료구조에 추가하는 코드를 보자. std::mutliset names; void logAndAdd(const std::string& name) { auto now = std::chrono::system_clock:now(); // 현재 시간 측정 log(now, "logAndAdd"); // 로그를 기록 name.emplace(name); // 이름을 추가 } std::string petName("Darla"); logAndAdd(petName); // 1. 왼값 std::string logAndAdd(std::string("Per..

Advanced C++ 2021.04.14

[Modern C++] (5-1) 오른값 참조, 이동 의미론, 완벽전달

이동 의미론(Move Semantics)과 완벽 전달(Perfect Forwarding) Move Semantics: 비싼 복사 연산을 덜 비싼 이동 연산으로 대체할 수 있다. Perfect Forwarding: 임의의 인수들을 받아서 다른 함수로 전달하는 함수를 작성할 때, 정확히 같은 타입의 인수로 전달할 수 있다. 1. std::move와 std::forward를 숙지한다. std::move는 주어진 인수를 무조건 오른값으로 캐스팅하고, std::forward는 특정 조건이 만족될 때에만 그런 캐스팅을 수행한다. - std::move의 구현 namespace std { // C++ 11 template typename remove_reference::type&& move(T&& param) { us..

Advanced C++ 2021.04.12

[C++] 형 변환 (2) dynamic_cast / static_cast / reinterpret_cast / const_cast

C++ 스타일의 클래스 간 명시적 형변환을 알아본다. dynamic_cast / static_cast / reinterpret_cast / const_cast dynamic_cast(expression) dynamic_cast는 런타임에 expression의 타입을 확인하여 type-id로 형 변환이 가능한지 검사한다. 참조나 포인터에 대해서만 사용가능하다. RTTI, 런타임 형식 정보를 사용하기 때문에 다른 캐스팅보다 느리다. 안전한 캐스팅을 제공하며 캐스팅이 실패하면 0 포인터, 즉 nullptr를 반환한다. 참고 : docs.microsoft.com/ko-kr/cpp/cpp/dynamic-cast-operator?view=msvc-160 - 업 캐스팅 // dynamic_cast_1.cpp // c..

Advanced C++ 2021.04.01

[C++] 형 변환 type casting

자료형과 관련된 용어 Type expression = ActualType inst; 위 expression이라는 변수를 선언했을 때, expresssion을 표현식이라하고 expression을 선언하기 위해 사용한 타입을 표현식의 타입이라하고 실제 인수가 가리키는 타입을 실제 타입이라고 한다. Implicit Conversion 암묵적 형변환 컴파일러가 자료를 재해석하여 자동적으로 자료형을 변환해주는 것을 의미한다. 변환될 타입의 범위가 실제 타입보다 작은경우 (double (8)-> float(4), unsigned long long -> long/int) narrow conversion 좁은 범위의 변환이 일어나고 컴파일러 경고가 나타난다. int a = 1.0f; // float -> int : n..

Advanced C++ 2021.04.01

[Modern C++] (3-2) 현대적 C++에 적응하기

현대적 C++ 기능을 잘 쓸 수 있도록 관련 내용을 정리한다. - 목록 1. iterator보다 const_iterator를 선호한다. 2. 예외를 방출하지 않을 함수는 noexcept로 선언한다. 3. 가능하면 항상 constexpr을 사용한다. 4. const 멤버 함수를 스레드에 안전하게 작성한다. 5. 특수 멤버 함수들의 자동 작성 조건을 숙지한다. 1. iterator보다 const_iterator를 선호한다. 원소를 바꿀 필요가 없는 반복자를 사용하는 함수에 const_iterator를 사용하도록 한다. cbegin()과 cend()는 const_iterator를 반환한다. std::vector values; // ... auto iter = std::find(values.cbegin(), v..

Advanced C++ 2021.03.26

[Modern C++] (3-1) 현대적 C++에 적응하기

현대적 C++ 기능을 잘 쓸 수 있도록 관련 내용을 정리한다. - 목록 1. 객체 생성시 괄호와 중괄호의 차이점을 안다. 2. 0과 NULL보다 nullptr을 선호한다. 3. typedef보다 별칭 선언을 선호한다. 4. 범위 없는 enum보다 범위 있는 enum을 선호한다. 5. 정의되지 않은 비공개 함수보다 삭제된 함수를 선호한다. 6. 재정의 함수들을 override로 선언한다. 1. 객체 생성시 괄호와 중괄호의 차이점을 안다. - C++11에서 변수 초기화 방법 // 괄호와 중괄호를 이용한 초기화 int x(0); int y = 0; int z{ 0 }; int w = { 0 }; 중괄호를 이용한 초기화의 특징: 균일 초기화 Uniform Intialization 모든 초기화에 사용가능한 단 한..

Advanced C++ 2021.03.25