C++11/14/17/20의 새로운 기능
C++11부터 C++20까지는 많은 새로운 기능이 추가되었습니다. 이러한 기능들은 코드의 가독성을 높이고 성능을 최적화하는 데 도움을 줍니다.
C++11의 주요 기능
1. auto
키워드
auto
키워드를 사용하면 변수의 타입을 자동으로 추론할 수 있습니다.
#include <iostream>
int main() {
auto x = 10; // int로 추론
auto y = 3.14; // double로 추론
auto s = "Hello"; // const char*로 추론
std::cout << x << " " << y << " " << s << std::endl;
return 0;
}
2. nullptr
nullptr
는 포인터의 null 값을 나타내는 데 사용됩니다. 기존의 NULL
이나 0
대신 사용할 수 있습니다.
int* p = nullptr;
3. 람다 함수
람다 함수는 익명 함수를 정의하는 데 사용됩니다.
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
std::for_each(vec.begin(), vec.end(), [](int x) {
std::cout << x << " ";
});
std::cout << std::endl;
return 0;
}
4. std::unique_ptr
와 std::shared_ptr
스마트 포인터는 동적 메모리 관리를 자동화하여 메모리 누수를 방지합니다.
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "Constructor" << std::endl; }
~MyClass() { std::cout << "Destructor" << std::endl; }
};
int main() {
std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();
std::shared_ptr<MyClass> ptr2 = std::make_shared<MyClass>();
return 0;
}
C++14의 주요 기능
1. 제너릭 람다
C++14에서는 람다 함수의 매개변수 타입을 자동으로 추론할 수 있습니다.
auto add = [](auto a, auto b) {
return a + b;
};
std::cout << add(1, 2) << std::endl; // int
std::cout << add(1.5, 2.5) << std::endl; // double
2. std::make_unique
C++14에서는 std::make_unique
가 도입되어 더 간편하게 std::unique_ptr
을 생성할 수 있습니다.
auto ptr = std::make_unique<int>(10);
C++17의 주요 기능
1. 구조적 바인딩
구조적 바인딩을 사용하면 튜플이나 구조체의 멤버를 쉽게 분해할 수 있습니다.
#include <iostream>
#include <tuple>
int main() {
std::tuple<int, double, std::string> t(1, 2.5, "hello");
auto [i, d, s] = t; // 구조적 바인딩
std::cout << i << " " << d << " " << s << std::endl;
return 0;
}
2. if
와 switch
의 초기화
C++17에서는 if
와 switch
문에서 초기화 문을 사용할 수 있습니다.
#include <iostream>
int main() {
if (int x = 10; x > 5) {
std::cout << "x is greater than 5" << std::endl;
}
return 0;
}
C++20의 주요 기능
1. 컨셉 (Concepts)
컨셉은 템플릿 매개변수의 요구 조건을 명확히 정의하는 기능입니다.
#include <iostream>
#include <concepts>
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template<Addable T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << add(1, 2) << std::endl;
std::cout << add(1.1, 2.2) << std::endl;
return 0;
}
2. 범위 (Ranges)
범위 라이브러리를 사용하면 더 간결하게 반복자 기반의 코드를 작성할 수 있습니다.
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
for (int x : vec | std::ranges::views::filter([](int i) { return i % 2 == 0; })) {
std::cout << x << " ";
}
std::cout << std::endl;
return 0;
}
실습 문제
문제 1: C++11/14/17/20 기능 활용하기
다음 코드에서 C++11/14/17/20의 기능을 사용하여 코드를 간결하고 효율적으로 만드세요.
main.cpp
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include <tuple>
int main() {
// C++11: auto, nullptr
int x = 10;
int* p = 0;
// C++11: 람다
std::vector<int> vec = {1, 2, 3, 4, 5};
std::for_each(vec.begin(), vec.end(), [](int x) { std::cout << x << " "; });
std::cout << std::endl;
// C++11: 스마트 포인터
std::unique_ptr<int> ptr1(new int(10));
std::shared_ptr<int> ptr2(new int(20));
// C++14: 제너릭 람다
auto add = [](int a, int b) { return a + b; };
std::cout << add(1, 2) << std::endl;
// C++17: 구조적 바인딩
std::tuple<int, double, std::string> t(1, 2.5, "hello");
int i;
double d;
std::string s;
std::tie(i, d, s) = t;
std::cout << i << " " << d << " " << s << std::endl;
// C++20: 컨셉
auto add20 = [](int a, int b) { return a + b; };
std::cout << add20(1, 2) << std::endl;
return 0;
}
해답:
main.cpp (최적화)
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include <tuple>
#include <concepts>
#include <ranges>
int main() {
// C++11: auto, nullptr
auto x = 10;
int* p = nullptr;
// C++11: 람다
std::vector<int> vec = {1, 2, 3, 4, 5};
std::for_each(vec.begin(), vec.end(), [](int x) { std::cout << x << " "; });
std::cout << std::endl;
// C++11: 스마트 포인터
auto ptr1 = std::make_unique<int>(10);
auto ptr2 = std::make_shared<int>(20);
// C++14: 제너릭 람다
auto add = [](auto a, auto b) { return a + b; };
std::cout << add(1, 2) << std::endl;
// C++17: 구조적 바인딩
auto t = std::make_tuple(1, 2.5, "hello");
auto [i, d, s] = t;
std::cout << i << " " << d << " " << s << std::endl;
// C++20: 컨셉
auto add20 = [](int a, int b) { return a + b; };
std::cout << add20(1, 2) << std::endl;
// C++20: 범위
for (int x : vec | std::ranges::views::filter([](int i) { return i % 2 == 0; })) {
std::cout << x << " ";
}
std::cout << std::endl;
return 0;
}
이제 열두 번째 날의 학습을 마쳤습니다. C++11/14/17/20의 새로운 기능을 이해하고, 이를 사용하여 코드를 최적화하는 방법을 학습했습니다.
질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "고급 상속 및 다형성 기법"에 대해 학습하겠습니다.
'-----ETC----- > C++ 성능 최적화 및 고급 테크닉 시리즈' 카테고리의 다른 글
[C++ 성능 최적화 및 고급 테크닉] Day 14: CRTP (Curiously Recurring Template Pattern) 사용법 (0) | 2024.08.01 |
---|---|
[C++ 성능 최적화 및 고급 테크닉] Day 15: 멀티스레딩의 기본 개념 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 13: 고급 상속 및 다형성 기법 (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 11: 표현식 템플릿 (Expression Templates) (0) | 2024.08.01 |
[C++ 성능 최적화 및 고급 테크닉] Day 9: 완벽한 전달 (Perfect Forwarding) (0) | 2024.08.01 |