본문 바로가기
-----ETC-----/C++ 성능 최적화 및 고급 테크닉 시리즈

[C++ 성능 최적화 및 고급 테크닉] Day 12: C++11/14/17/20의 새로운 기능 활용

by cogito21_cpp 2024. 8. 1.
반응형

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_ptrstd::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. ifswitch의 초기화

C++17에서는 ifswitch 문에서 초기화 문을 사용할 수 있습니다.

#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의 새로운 기능을 이해하고, 이를 사용하여 코드를 최적화하는 방법을 학습했습니다.

질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "고급 상속 및 다형성 기법"에 대해 학습하겠습니다.

반응형