전체를 다 보기에는 양이 많고, 아는 부분도 많아 필요한 부분만 정리하도록 하겠습니다.
▶ if, switch 문의 이니셜라이저 (C++17)
if 문과 switch문 안에 이니셜라이저를 넣는 기능이 추가되었습니다.
if (<이니셜라이저> ; <조건문>) { <본문> }
switch (<이니셜라이저> ; <표현식>) { <본문> }
위와 같은 형태로 주어지며, if문의 조건문 혹은 switch문의 표현식 및 본문에서 이를 사용할 수 있습니다.
▶ [[fallthorugh]] (C++17)
attribute에 해당하며, switch 문에서 폴스루 구문을 발견했는데 케이스가 비어 있지 않다면, 경고 메시지를 발생시킵니다. 이를 막기 위해 [[fallthrough]] 구문을 적어 방지합니다.
switch (backgroundColor) {
case Color::DarkBlue;
doSomething1();
[[fallthrough]]; // 경고 메세지 방지
case Color::DarkBlue;
doSomething2();
break;
case Color::DarkBlue;
break;
};
▶ 현재 함수 이름
함수에는 내부적으로 __func__이라는 로컬 변수가 정의되어 있으며, 이 변수는 현재 함수의 이름을 값으로 가지고 있어 활용 가능합니다.
▶ C 스타일 배열
초기화를 할 때 initializer_list로 초기화를 하면, 배열의 크기가 컴파일러가 알아서 지정해줄 수도 있고, 배열의 크기가 정해져있다면, initializer_list에 나온 원수 수만큼 초기화를 해주고 나머지는 0으로 초기화시켜줍니다. C++17부터는 std::size로 C 스타일 배열의 크기를 알아낼 수 있습니다. 그 전에는 sizeof로 사이즈를 구한 뒤 자료형 크기로 나누어 구하였습니다.
int myArray[3] = {2}; // {2, 0, 0}과 동일
unsigned int arraySize = std::size(myArray); // 3
▶ 구조적 바인딩 (C++17)
구조적 바인딩을 이용하면 여러 개의 변수를 선언할 때 배열, 구조체, 페어 또는 튜플의 값으로 초기화할 수 있습니다. 변수 선언과 동시에 구조적 바인딩을 통해 값을 할당할 때는 변수의 타입이 아닌 반드시 auto를 사용해야합니다. 구조적 바인딩은 표현식 값 개수가 반드시 일치해야하며, 배열 뿐만 아니라 모든 멤버가 Non-static이면서도 public으로 선언된 데이터 구조라면 어떤 것도 적용할 수 있습니다.
std::array<int, 3> values = { 11, 22, 33};
auto [x, y, z] = values;
struct Point {double mX, mY, mZ;};
Point point{1.0, 2.0, 3.0};
auto [x, y, z] = point;
▶ 범위 기반 for 문
C 스타일의 루프, initializer_list 및 STL처럼 iterator를 리턴하는 std::begin(), std::end() 메서드가 정의된 모든 타입에 적용이 가능합니다.
▶ shared_ptr 배열 (C++17)
shared_ptr에 배열도 저장할 수 있지만, 배열을 저장하는 shared_ptr을 생성할 때는 make_shared<>()를 사용할 수 없고, 다음과 같이 작성해야 합니다.
shared_ptr<Employee[]> employees(new Employee[10]);
▶ 유니폼 초기화
C++11 이전에는 구조체와 클래스의 타입 변수 초기화 방법이 달랐습니다.
Struct a = {10, 10, 2.5};
Class b(10, 10, 2.5);
C++11 이후로는 타입을 초기화할 때 {...} 문법을 사용하는 유니폼 초기화를 따르도록 통일 됐습니다. 중괄호로 빈 집합 표시를 해주면 제로 초기화를 할 수도 있습니다. 유니폼 초기화를 사용하면 축소 변환을 방지할 수 있는데, 이는 float가 int로 변환 되어 초기화 되는 것을 방지시킬 수 있습니다.
void func(int i) {};
int main()
{
int x = {3.14}; // Error!
func({3.14}); // Error!
func(3.14); // OK! But, Warning;
};
▶이니셜라이저 리스트 초기화
이니셜라이저는 다음과 같이 두개가 존재합니다.
- 복제 리스트 초기화 : T obj = {arg1, arg2, ...};
- 직접 리스트 초기화 : T obj{arg1, arg2, ...};
C++17부터 auto 추론 기능과 관련하여 크게 달라 졌는데, C++17 이전에는 둘다 initializer_list<>로 처리 되었지만, 이후에는 auto는 직접 리스트 초기화에 대해 값 하나만 추론하게 되었습니다. 또한 복제 리스트 초기화에서 중괄호 안에 나온 원소는 반드시 타입이 모두 같아야만 합니다.
auto a = {11}; // initializer_list<int>
auto b = {11, 22}; // initializer_list<int>
auto a{11}; // int!!
auto b{11, 22}; // 원소가 너무 많다는 에러 발생
▶ literal pooling
Literal pooling이란 string literal은 내부적으로 메모리의 읽기 전용 영역에 저장되는데, 컴파일러는 같은 string literal이 코드에 여러 번 나오면 그 중 한 string에 대한 레퍼런스를 재사용하는 방식으로 메모리를 절약합니다. 즉 hello가 500번 나와도 메모리 공간을 딱 하나만 할당합니다. 또한 string literal은 메모리의 읽기 전용 영역에 존재하므로, const char가 n개인 배열로 타입을 지정하여 변경할 수 없도록 합니다.
▶ raw string litral
문자열 표기에 있어 "만 사용한다면 \t, \n과 같은 이스케이프 시퀀스를 사용해야기 때문에, 안의 문자를 문자 그대로 받아들이는 raw string literal이 존재합니다. 하지만 이는 안에 )"를 표기할 수 없기에, extended string literal이 존재하는데 이는 R"*( ... )*"의 형태로 *에는 최대 16문자로 표현할 문자열에 들어가 있는 문자열이 아니면 무엇이든 들어가도 괜찮으며, 고유한 구분자 시퀀스를 앞뒤에 두는 것을 통해 표현가능합니다. 밑의 예시는 *에 -를 넣은 경우 입니다.
const char *str = R"(Is this? )";
const char *str = R"-(Is this? )-";
▶ std::string literal
표준 사용자 정의 리터럴 s를 사용하려면 using namespace std::string_literals; 또는 using namespace std;가 필요합니다.
auto string1 = "Hello Wolrd"; // const char*
auto string1 = "Hello Wolrd"s; // std::string
▶ std::string_view (C++17)
C++17 이전에는 읽기 전용 스트링을 받는 함수의 매개변수 타입을 쉽게 결정할 수 없었습니다. const char*로 지정하면, std::string에서 c_str() 혹은 data()를 이용하여 string을 const char*로 변환해서 호출해야 했습니다. 이를 해결한 것이 string_view로 string_view는 const string& 대신에 사용 가능하며, 스트링을 복사하지 않아 오버헤드도 존재하지 않습니다.
string과 string_view는 서로 연결/결합할 수 없습니다. 결합하려면 .data()를 통해 바꾸어 합쳐줘야 합니다. std::string은 값 전달하는 경우 이를 복사해서 오버헤드가 생기는 반면, string_view는 길이와 포인터만 가지고 있기에, 참조 전달에 가깝습니다. 이는 string, const char*, literal에 대해 모두 오버헤드 없이 만족스럽게 참조 전달을 진행할 수 있습니다.
string_view를 사용하는 것만으로는 string이 생성되지 않기에 명시적으로 string으로 변환하거나, data를 통해 변환될 수 있도록 해주어야 합니다. string_view 또한, 리터럴 sv를 통해 string_view literal이 구현가능하며, using namespace std::string_literals; 또는 using namespace std;가 필요합니다.
'C++공부 > 그 외의 C++' 카테고리의 다른 글
전문가를 위한 C++ : 13 ~ 15장 (0) | 2022.07.14 |
---|---|
전문가를 위한 C++ : 10 ~ 12장 (0) | 2022.07.13 |
전문가를 위한 C++ : 4 ~ 9장 (0) | 2022.07.12 |
Optimized C++ 9 - 13장 (0) | 2022.07.08 |
Optimized C++ : 4 ~ 8장 (0) | 2022.07.07 |