C++11에서의 람다, auto, function, bind, final, override 활용법

람다 표현식 (Lambda Expression)

C++11의 람다는 익명의 함수 객체를 정의하고 생성하여 코드 작성의 간편성을 높이는 기능입니다. 기본 구문은 다음과 같습니다:

[capture](parameters) mutable exception -> return-type { function-body }

이 구성 요소들은 각각 다음을 의미합니다:

  • 캡처 리스트 (capture): 외부 변수 접근 방식을 지정합니다. =는 값 전달, &는 참조 전달, this는 클래스 멤버 접근을 허용합니다.
  • 파라미터 리스트: 함수 호출 시 전달되는 인자들입니다. 생략 가능하며, (int a, int& b)와 같이 값 또는 참조 방식으로 전달할 수 있습니다.
  • mutable: 값 캡처된 변수의 수정을 허용합니다. 기본적으로 람다 함수는 const입니다.
  • 예외 선언: 함수가 던질 수 있는 예외 유형을 명시합니다. 예: throw(int).
  • 반환 타입 지정자: -> 이후에 반환 타입을 명시합니다. 컴파일러가 자동 추론 가능한 경우 생략 가능합니다.
  • 함수 본체: 실제 실행 로직이 포함되며, 반드시 존재해야 합니다.

auto 키워드

auto는 초기화 식에서 타입을 자동 추론하거나, 함수 반환 타입의 자리 표시자로 사용됩니다.

auto value = 42;                    // int
auto ch = 'A';                      // char
auto it = std::vector<int>::begin(); // vector<int>::iterator

// 함수 반환 타입의 자리 표시자
template <typename T1, typename T2>
auto combine(T1 t1, T2 t2) -> decltype(t1 + t2) {
    return t1 + t2;
}

std::function

std::function은 다양한 호출 가능한 대상을 포장하고 재사용할 수 있게 해주는 다형성 함수 래퍼입니다.

// 자유 함수 저장
void print_value(int n) { std::cout << n << std::endl; }
std::function<void(int)> func = print_value;
func(5);

// 람다 저장
std::function<void()> lambda_func = []() { std::cout << "Hello!" << std::endl; };
lambda_func();

// 멤버 함수 저장
struct Calculator {
    int add(int a, int b) const { return a + b; }
};
std::function<int(const Calculator&, int, int)> f = &Calculator::add;
Calculator calc;
std::cout << f(calc, 3, 4) << std::endl;

std::bind

std::bind는 함수나 멤버 함수의 일부 인자를 미리 바인딩하거나 인자 순서를 조정하는 데 사용됩니다.

void greet(int x, int y, int z) {
    std::cout << x << " " << y << " " << z << std::endl;
}

auto f1 = std::bind(greet, 10, 20, 30);       // 모든 인자 고정
f1(); // 출력: 10 20 30

auto f2 = std::bind(greet, std::placeholders::_1, std::placeholders::_2, 30);
f2(1, 2); // 출력: 1 2 30

auto f3 = std::bind(greet, std::placeholders::_2, std::placeholders::_1, 30);
f3(1, 2); // 출력: 2 1 30

// 참조 전달 예제
int a = 5, b = 10;
auto f4 = std::bind([](int& x, int& y) { x++; y++; }, a, std::placeholders::_1);
f4(b);
std::cout << a << ", " << b << std::endl; // 출력: 5, 11 (a는 값 복사, b는 참조 전달)

nullptr

nullptrNULL과 달리 특정한 포인터 타입을 나타내는 키워드입니다. 정수 0이 아니며, 오버로드 해결에 유리합니다.

char* ptr = nullptr;
void func(int);
void func(char*);

func(0);        // 호출: func(int)
func(nullptr);  // 호출: func(char*)

final 및 override

상속 체계를 보다 안전하게 관리하기 위한 키워드입니다.

  • final: 클래스나 가상 함수가 더 이상 상속되지 않도록 제한합니다.
  • override: 부모 클래스의 가상 함수를 정확히 재정의했는지 컴파일 시점에 검증합니다.
class Base {
public:
    virtual void method() {}
    virtual void method2(int) {}
    virtual void method3() const {}
};

class Derived : public Base {
public:
    void method() override {}             // OK
    void method2(float) override {}      // 에러: 파라미터 불일치
    void method3() override {}           // 에러: 상수성 불일치
    void method4() override {}           // 에러: 부모의 가상 함수 아님
};

참고로, finaloverride는 다른 컨텍스트에서는 일반 식별자로 사용 가능합니다.

태그: Lambda Expression auto keyword std::function std::bind nullptr

7월 12일 18:25에 게시됨