전체 글
[Effective Modern C++] 9. typedef보다 별칭 선언을 선호하자
[Effective Modern C++] 9. typedef보다 별칭 선언을 선호하자
2022.08.28아래처럼 typedef는 템플릿화를 지원하지 않지만 별칭 선언은 지원한다. template // MyAllocList::type은 std::list와 동의어이다. struct MyAllocList { typedef std::list type; }; MyAllocList::type lw; // 클라이언트 코드 // 별칭 템플릿은 훨씬 더 간단하고, 직접적으로 표현할 수 있다. template // MyAllocList::type은 std::list와 동의어이다. using MyAllocList = std::list; MyAllocList lw; // 클라이언트 코드 또 별칭 템플릿에서는 "::type" 접미어를 붙일 필요가 없다. 그래서 C++11의 모든 타입 변환에 대한 별칭 템플릿 버전들을 C++14에..
[Effective Modern C++] 8. 0과 NULL보다 nullptr을 사용하자
[Effective Modern C++] 8. 0과 NULL보다 nullptr을 사용하자
2022.08.28리터럴 0은 int이지 포인터가 아니다. 실용적인 관점에서는 NULL도 마찬가지이다. 그러나 NULL의 경우에는 다소 불확실한 세부사항이 존재한다. 구현이 NULL에 int 이외의 정수 타입을 부여할 수도 있기 때문이다. 이 점이 이야기하는 주된 문제는 포인터와 정수 타입에 대한 오버로딩이 의외의 방식으로 해소된다는 점이었다. 0이나 NULL로 그런 오버로딩 된 함수를 호출했을 때, 포인터를 받는 오버로딩된 함수가 호출되는 일은 없다. 반면 nullptr을 사용하면 오버로딩이 예상과 다르게 해소되는 일이 없다. 그 뿐만 아니라, nullptr는 코드의 명확성도 높여준다. 템플릿의 타입 추론시에도, 0과 NULL은 정수 타입으로 추론하는 반면 nullptr은 포인터 타입으롤 추론한다. // f의 세 가지 ..
[Effective Modern C++] 7. 객체 생성 시 괄호(())와 중괄호({})를 구분하자
[Effective Modern C++] 7. 객체 생성 시 괄호(())와 중괄호({})를 구분하자
2022.08.28중괄호 초기화(균일화 초기화) 변수 초기화 방법은 기존의 초기화 방법에, 중괄호 초기화 방법을 더해 총 4가지 방법으로 변수를 초기화 할 수 있다. int a(0); // 초기치를 괄호로 감싼 예 int b = 0; // 초기치를 "=" 다음에 지정한 예 int c{ 0 }; // 초기치를 중괄호로 감싼 예 int d = { 0 }; // "="와 중괄호로 초기치를 지정한 예 이번 항목의 나머지 부분에서는 이러한 등호와 중괄호 구문은 무시한다. 대체로 C++은 이를 중괄호만 사용한 구문과 동일하게 취급하기 때문이다. 중괄호 초기화를 이용하면 이전에는 표현할 수 없었던 방식의 객체 생성을 표현할 수 있다. std::vector v{ 1, 3, 5 }; // v의 초기 내용은 1, 3, 5 중괄호 구문은 비..
[Effective Modern C++] 6. auto가 원치 않은 타입으로 추론 될 때에는 명시적 타입의 초기화를 생각하자
[Effective Modern C++] 6. auto가 원치 않은 타입으로 추론 될 때에는 명시적 타입의 초기화를 생각하자
2022.08.27일단, 보이지 않는 프록시 타입 때문에 auto가 초기화 표현식의 타입을 잘못 추론할 수 있다는 점을 알아야한다. 예를 들어, std::vector::operator[]의 반환 타입은 bool&이 아니라 어떤 프록시 클래스 타입이다. 프록시 클래스 중에는 사용자에게 명백히 드러나도록 설계된 것들도 있지만(std::shared_ptr, std::unique_ptr) 보통 보이지 않도록 숨겨져 있다. 그렇기 때문에 보통 프록시 클래스는 auto와 잘 맞지 않는다. 때문에 다음과 같은 코드는 미정의 동작을 유발한다. // Widget을 하나 받고 std::vector을 돌려주는 다음과 같은 함수가 하나 있다고 하자. std::vector features(const Widget& w); // 해당 bool 값들..
[Effective Modern C++] 5. 명시적 타입 선언보다는 auto를 선호하자
[Effective Modern C++] 5. 명시적 타입 선언보다는 auto를 선호하자
2022.08.15아래처럼 auto는 반드시 초기화가 필요하다. int x1; // 문맥에 따라서는 초기화되지 않을 수 있음 auto x2; // 오류! 초기치가 꼭 필요함 auto x3 = 0; // 양호함: x3의 값이 잘 정의됨 여기서 반복자의 역참조를 통해 초기화되는 지역 변수 하나를 간단하게 선언한 아래의 코드를 보자. // b에서 e까지의 구간에 있는 모든 요소에 대해 dwim("do what I mean") 알고리즘을 수행한다. template void dwim(It b, It e) { for (; b != e; ++b) { typename std::iterator_traits::value_type currValue = *b; ... } } // auto를 사용하면 훨씬 간단하게(적은 타이핑으로) 선언할 수 ..
[Effective Modern C++] 4. 추론된 타입을 파악하는 방법을 알아두자
[Effective Modern C++] 4. 추론된 타입을 파악하는 방법을 알아두자
2022.08.06IDE 편집기 IDE(통합 개발 환경)의 코드 편집기 중에는 프로그램 객체(변수, 매개변수, 함수 등) 위에 마우스 커서를 올리면 그 객체의 타입을 표시해 주는 것이 많다. const int theAnswer = 42; auto x = theAnswer; // int auto y = &theAnswer; // const int* 이런 일이 가능하려면 편집기의 코드가 어느 정도는 컴파일 가능한 상태여야 한다. 컴파일러가 코드를 파싱 해서 타입 추론을 수행할 수 있을 정도로 편집기의 코드가 완성되어 있지 않으면 편집기는 요청된 객체의 타입을 표시할 수 없다. 일반적으로 int와 같은 간단한 타입의 경우에는 IDE가 알려준 정보가 쓸만하지만, 좀 더 복잡한 타입이 관여할 때에는 IDE가 표시한 정보가 그리 도..
[Effective Modern C++] 3. decltype의 작동 방식을 숙지하자
[Effective Modern C++] 3. decltype의 작동 방식을 숙지하자
2022.08.06decltype은 주어진 이름이나 표현식의 구체적인 타입을 반환한다. 아래의 예시를 보자. const int i = 0; // decltype(i)은 const int bool f(const Widget& w); // decltype(w)은 const Widget&, decltype(f)은 bool(const Widget&) struct Point { int x, y; // decltype(Point::x)은 int, decltype(Point::y)은 int }; Widget w; // decltype(w)은 Widget if (f(w)) ... // decltype(f(w))은 bool template // std::vector class vector { public: ... T& operator[]..
[Effective Modern C++] 2. auto의 타입 추론 규칙을 숙지하자
[Effective Modern C++] 2. auto의 타입 추론 규칙을 숙지하자
2022.08.06항목 1에서 템플릿 타입 추론은 아래의 함수 템플릿을 사용하여 설명한다. template void f(ParamType param); f(expr); // 호출 auto를 이용해서 변수를 선언할 때 auto는 템플릿의 T와 동일한 역할을 하며, 변수의 타입 지정자(type specifier)는 ParamType과 동일한 역할을 한다. 아래의 예시를 보자. // 여기서 x의 타입 지정자는 그냥 auto 자체이다. 반면, 다음 선언에서 auto x = 27; // 타입 지정자는 const auto이다. const auto cx = x; // 타입 지정자가 const auto&이다. const auto& rx = x; // 이 예들에서 x와 cx, rx의 타입들을 추론할 때, 컴파일러는 마치 선언마다 템플릿 ..
[Effective Modern C++] 1. 템플릿 타입 추론 규칙을 숙지하자
[Effective Modern C++] 1. 템플릿 타입 추론 규칙을 숙지하자
2022.08.06아래는 함수 템플릿의 선언과 호출부의 의사 코드이다. template void f(ParamType param); f(expr); // f를 호출 컴파일 도중 컴파일러는 expr을 이용해서 두 가지 타입을 추론하는데, 하나는 T에 대한 타입 추론이고 하나는 ParamType에 대한 타입 추론이다. 이 두타입은 다른 경우가 많은데, 이는 ParamType에 보통 const나 참조자(&, &&) 같은 수식어들이 붙기 때문이다. 예를 들어 아래처럼 템플릿의 선언을 하고 호출한다고 하자. // 선언 template void f(const T& param); --- // 호출 int x = 0; f(x); 이 경우 T는 int로 추론되나 ParamType은 const int&로 추론된다. T에 대해 추론된 타입은..
[Effective C++] 55. Boo子有親! 부스트를 늘 여러분 가까이에
[Effective C++] 55. Boo子有親! 부스트를 늘 여러분 가까이에
2022.07.24이번 장은 Boost와 친해지라는 내용의 항목이다. 부스트(http://boost.org)는 C++ 개발자들의 단체이자 무료 다운로드가 가능한 C++라이브러리 집합을 동시에 일컫는 고유명사이다. 부스트 외에도 여러 단체 및 웹사이트가 있으나, 부스트는 C++ 표준화 위원회와 밀접한 관계에 있으며, 실제로 Boost에서 사용되던 것이 c++표준으로 추가된 경우도 있다. 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..
[Effective C++] 54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자
[Effective C++] 54. TR1을 포함한 표준 라이브러리 구성요소와 편안한 친구가 되자
2022.07.24C++98의 기존 기능 1. 표준 템플릿 라이브러리(STL) 2. iostream 3. 국제화 지원 4. 수치 처리 자원 5. 예외 클래스 계통 6. C89의 표준 라이브러리 TR1을 통해 명시된 새로운 구성요소 1. 스마트 포인터 2. tr1::function 3. tr1::bind 4. 해시 테이블 5. 정규 표현식 6. tuple 7. tr1::array 8. tr1::mem_fn 9. tr1::reference_wrapper 10. 난수발생 11. 특수 용도의 수학 함수 12. C99 호환석 확장 기능 13. 타입 특성정보 14. tr1::result_of 요약 최초에 상정된 표준 C++라이브러리의 주요 구성요소는 STL, iostream, 로케일 등이다. 여기에는 C89의 표준 라이브러리도 포함..
[Effective C++] 53. 컴파일러 경고를 지나치지 말자
[Effective C++] 53. 컴파일러 경고를 지나치지 말자
2022.07.24우리는 우리가 사용하고 있는 컴파일러가 띄워주는 에러 메시지들에 어느 정도 익숙해지고 나면, 이 외의 다른 메시지들도 어떤 것은 넘어가도 되고, 어떤 것은 없애주어야 하는지 이해하게 되는 수준이 오게 된다. 우리는 경고 메시지의 참 뜻을 명확하게 이해해야 하며, 지워나가는 습관을 들어야 한다. 요약 컴파일러 경고를 쉽게 지나치지 말자. 컴파일러에서 지원하는 최고 경고 수준에도 경고 메시지를 내지 않고 컴파일되는 코드를 만드는 쪽에 전력을 다하자. 컴파일러 경고에 너무 기대는 인생을 지양하자. 컴파일러마다 트집을 잡고 경고를 내는 부분들이 천차만별이기 때문이다. 지금 코드를 다른 컴파일러로 이식하면서 여러분이 익숙해져 있는 경고 메시지가 온 데 간 데 없이 사라질 수 있다.