C++을 학교에서만 쓰다가 현업으로 뛰어드려고 보니 (상대적으로) 최근 문법의 C++가 눈에 밟히기 시작하더라. 근데, 도대체 뭐가 추가된거고 다 쓰는 것이 맞을까? 라는 생각이 들어 여기저기 자료 조사를 한 내용과 쓰면서 느낀 점들을 조금 정리해봤다.
서론을 시작하기도 전에 결론을 던져보자면 모던 C++은 옛날 C++만큼 고리타분하지 않으며 잘 사용하면 C++의 강점을 유지하면서 생산성을 향상시킬 수 있기 때문에 적극적으로 배우고 적용하는 것을 추천한다. 다만 모던 C++을 적용하게 된다면 언어 스펙이 덕지덕지 늘어나면서 괴상한 코드가 나오기 좋기 때문에 코드 리뷰 등을 통해 항상 코드를 비판하고 비판받을 필요가 있다. 어짜피 배움과 상호비판은 개발자의 숙명이니 그려러니 하자.
C++을 쓰지 않는 독자는 적당히 훑어보면서 "아 이 언어는 이런 것도 (이제야) (안) 되네!" 라는 감상을 가지거나 "얘네는 성능 최적화 하겠다고 이런 짓들도 하는구나", 또는 "가독성을 위해 언어 스펙을 제한할 수도 있다" 와 같이 일반적인 인사이트 정도만 얻어가면 충분할 것 같다. 만약 그동안 잊고 있었던 call-by-reference / call-by-value 개념이나 객체 복사, 메모리 관리 등 뇌에서 반쯤 날려버린 개념들을 다시 떠올릴 수 있다면 굉장히 뿌듯할 것 같다.
서론 전에 글만 가득해서 독자들이 탈주할까봐 바치는 조공 — https://unsplash.com/photos/mKWKbHZaN-0
조공은 많을 수록 좋다 — https://unsplash.com/photos/00MAHmixauc
괴애애애앵장히 많으나 개인적으로 자주 쓰는 것들을 나름 추려서 정리해 보았다. 각 기능들의 내부 구현 방법들이 생각보다 복잡하기 때문에 "아 이런 것들도 있구나" 정도만 파악하고 실제로 사용할 때는 자세히 설명한 글들을 읽고 사용하는 것들을 권장한다. 대부분의 기능들은 잘못 쓰기 쉬우며 잘못 쓰면 되려 가독성과 성능이 나빠진다.
auto my_name = "cho";
for (int i = 0; i < a.size(); i++) {
은 잊자for (int i : a) {
와 같이 매우 간결하게 컨테이너에 대한 이터레이션이 가능
for (int &i : a) {
)shared_ptr
, unique_ptr
, weak_ptr
)
my_vector.push_back(my_obj);
은 복사가 일어나서 불필요한 비용이 생길 수 있음my_vector.push_back(std::move(my_obj));
은 복사를 방지할 수도 있음. 대신 이 뒤로 my_obj
에 접근하면 예상치 못한 작동을 할 수 있음enum <ENUM_NAME> {}
) 은 unscoped enum이라고 불림enum class(struct) <ENUM_NAME> : <INTERNAL_TYPE>
으로 선언을 할 수 있음int x = MY_ENUM::ENUM1
같이 간접적 형 변환이 불가능하기 때문에 의도치 않은 형 변환으로 인한 오류를 방지할 수 있음
static_cast
사용push_back
은 객체를 생성하고 복사하나
vector<pair<int, int>>().push_back(create_pair<int,int>(10, 20));
emplace_back
은 전달 받은 인자 값들을 사용해서 컨테이너 내에서 객체에 대한 생성자를 호출하고 알아서 컨테이너에 추가해주기 때문에 복사 과정이 불필요
vector<pair<int, int>>().emplace_back(10, 20);