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

[C++ 성능 최적화 및 고급 테크닉] Day 9: 완벽한 전달 (Perfect Forwarding)

by cogito21_cpp 2024. 8. 1.
반응형

완벽한 전달의 중요성

완벽한 전달(perfect forwarding)은 C++ 템플릿 프로그래밍에서 매개변수를 정확히 전달하는 기법입니다. 이를 통해 함수 템플릿에서 인자를 원래의 L-값 또는 R-값으로 전달할 수 있습니다. 이 기법은 주로 std::forward를 사용하여 구현됩니다.

 

템플릿 함수와 인자 전달

템플릿 함수에서 인자를 전달할 때, 인자의 종류(L-값 또는 R-값)를 정확히 유지하는 것이 중요합니다. 잘못된 인자 전달은 불필요한 복사나 잘못된 동작을 초래할 수 있습니다.

 

std::forward 사용법

std::forward는 전달된 인자의 원래 특성을 유지하면서 전달합니다. 이를 통해 L-값 인자는 L-값으로, R-값 인자는 R-값으로 전달할 수 있습니다.

#include <iostream>
#include <utility>

void process(int& lval) {
    std::cout << "L-value reference" << std::endl;
}

void process(int&& rval) {
    std::cout << "R-value reference" << std::endl;
}

template<typename T>
void forwarder(T&& arg) {
    process(std::forward<T>(arg));
}

int main() {
    int x = 10;
    forwarder(x); // L-value 전달
    forwarder(10); // R-value 전달
    return 0;
}

 

위 예제에서 forwarder 함수는 std::forward를 사용하여 인자를 정확히 전달합니다.

 

완벽한 전달의 구현

완벽한 전달을 구현하기 위해서는 템플릿 함수에서 전달된 인자를 std::forward를 사용하여 전달합니다. 이를 통해 인자의 특성을 유지할 수 있습니다.

 

완벽한 전달 예제

#include <iostream>
#include <utility>

class MyClass {
public:
    MyClass() {
        std::cout << "Default Constructor" << std::endl;
    }
    MyClass(const MyClass&) {
        std::cout << "Copy Constructor" << std::endl;
    }
    MyClass(MyClass&&) noexcept {
        std::cout << "Move Constructor" << std::endl;
    }
};

void process(MyClass& obj) {
    std::cout << "L-value reference" << std::endl;
}

void process(MyClass&& obj) {
    std::cout << "R-value reference" << std::endl;
}

template<typename T>
void forwarder(T&& arg) {
    process(std::forward<T>(arg));
}

int main() {
    MyClass obj;
    forwarder(obj); // L-value 전달
    forwarder(MyClass()); // R-value 전달
    return 0;
}

 

위 예제에서 forwarder 함수는 std::forward를 사용하여 인자를 정확히 전달합니다.

 

실습 문제

문제 1: 완벽한 전달 구현하기

다음 코드에서 완벽한 전달을 구현하여 인자의 특성을 유지하세요.

 

main.cpp

#include <iostream>

void process(int& lval) {
    std::cout << "L-value reference" << std::endl;
}

void process(int&& rval) {
    std::cout << "R-value reference" << std::endl;
}

template<typename T>
void forwarder(T arg) {
    process(arg);
}

int main() {
    int x = 10;
    forwarder(x); // L-value 전달
    forwarder(10); // R-value 전달
    return 0;
}

 

해답:

main.cpp (완벽한 전달 구현)

#include <iostream>
#include <utility>

void process(int& lval) {
    std::cout << "L-value reference" << std::endl;
}

void process(int&& rval) {
    std::cout << "R-value reference" << std::endl;
}

template<typename T>
void forwarder(T&& arg) {
    process(std::forward<T>(arg));
}

int main() {
    int x = 10;
    forwarder(x); // L-value 전달
    forwarder(10); // R-value 전달
    return 0;
}

 

이제 아홉 번째 날의 학습을 마쳤습니다. 완벽한 전달의 중요성과 이를 구현하는 방법을 이해하고, 실습 문제를 통해 이를 적용하는 방법을 학습했습니다.

질문이나 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "inline 함수와 매크로의 사용"에 대해 학습하겠습니다.

반응형