람다 표현식 (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
nullptr은 NULL과 달리 특정한 포인터 타입을 나타내는 키워드입니다. 정수 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 {} // 에러: 부모의 가상 함수 아님
};
참고로, final과 override는 다른 컨텍스트에서는 일반 식별자로 사용 가능합니다.