이번 포스팅에서는 자료 구조와 알고리즘을 공부하기 전에 모던 C++ 주요 문법들에 대해 정리해 보려고 합니다.
Modern C++이란?
Modern C++은 C++11 후의 C++을 말합니다.
auto란?
컴파일러가 선언된 변수 또는 람다 식 변수의 초기화 식을 사용하여 타입을 추론하도록 지시하는 키워드입니다.
auto a1 = 10; // int
auto a2 = 3.14f; // float
auto a3 = "hello"; // const char*
auto a4 = "hello"s; // string
auto a5 = sqrt(2.0); // double
auto a6 = odds(); // vector<int>, vector<int> odds() { return {1, 3, 5, 7, 9}; }
auto a7 = a6.begin(); // vector<int>::iterator
auto lambda = [](int x) { return x * 2; };
using이란?
namespace와 별칭(Alias) 선언 시 사용할 수 있는 키워드입니다. 템플릿 별칭(Template alias)도 지원합니다. C++11 이전에는 typedef를, C++11 이후에는 using 사용을 권장합니다.
// C++11 이전
typedef unsigned int uint;
typedef pair<int, string> pis;
typedef double da10[10];
typedef void (*func)(int);
// C++11 이후
using uint = unsigned int;
using pis = pair<int, string>;
using da10 = double[10];
using func = void(*)(int);
// 템플릿 별칭
template<typename T>
using matrix1d = vector<T>;
// 사용 예시
da10 arr {};
matrix1d<float> vec(3);
func fp = &my_function; // void my_function(int n) { cout << n << endl; }
범위 기반 for 문(Range-based for)이란?
Iterable 컨테이너에 들어있는 모든 원소를 순차적으로 접근하는 C++11의 새로운 반복문입니다. 순차 접근하려는 컨테이너의 범위가 begin()과 end()로 정의되어 있어야 합니다.
vector<int> numbers {10, 20, 30};
// range-based for
for (int n : numbers) {
// n에 numbers의 원소가 복사됩니다.
cout << n << endl;
}
// 10
// 20
// 30
for (auto& n : numbers) {
// n에 numbers의 원소를 참조형으로 가져옵니다.
cout << n << endl;
}
// 10
// 20
// 30
for (const auto& n : numbers) {
// n에 numbers의 원소를 읽기 전용 참조형으로 가져옵니다.
cout << n << endl;
}
// 10
// 20
// 30
// range-based for is same as
for (auto iter = numbers.begin(); iter < numbers.end(); iter++) {
cout << *iter << endl;
}
// 10
// 20
// 30
람다 표현식(Lambda expression)이란?
이름 없는 함수 객체를 정의하는 방법입니다. 함수의 포인터 또는 함수 객체를 대체합니다.
// 람다 표현식으로 변수 선언
auto square = [](double a) { return a * a; };
cout << square(1.414) << endl;
struct Person {
string name;
int age;
// std::vector의 emplace_back 사용을 위한 constructor 정의
Person(string n, int a) : name(n), age(a) {}
};
vector<Person> students;
students.emlpace_back("Kim", 20);
students.emplace_back("Park", 27);
students.emplace_back("Lee", 22);
// 정렬 함수의 조건으로 람다 표현식 사용
sort(students.begin(), students.end(), [](const Person& p1, const Person& p2) { return p1.age < p2.age; });
for (const auto& s : students) {
cout << s.name << ", " << s.age << endl;
}
// Kim, 20
// Lee, 22
// Park, 27
chrono 라이브러리란?
OS 독립적으로 정밀한 시간을 측정할 수 있게 해주는 라이브러리이며, <chrono>애 정의되어 있습니다. 나노초(nano second) 단위까지 측정 가능합니다.
프로그램 동작 시간을 제대로 측정하려면 g++ 사용 시 -O2 옵션을 사용해야 하며, Visual Studio 사용 시에는 Release 모드로 빌드 해야 합니다.
// 시작 시간
auto start = chrono::system_clock::now();
// Do something ...
// 완료 시간
auto end = chrono::system_clock::now();
// 경과 시간
auto msec = chrono::duration<double>(end - start).count() * 1000;
cout << "Elapsed time : " << msec << "msec" << endl;
이번에는 모던 C++ 주요 문법에 대해 정리해 봤습니다.
이제 진짜 자료 구조와 알고리즘에 대해 공부해야겠네요.