반응형
일반 함수는 [반환형], [함수 이름], [인수] 를 입력하여 선언한다.
하지만 람다 함수는 이름이 없는 익명 함수로써 아래의 형태로 선언하여 사용하며, std::function 과 함께 사용시 재사용도 가능하다.
(참고 : std::function - 함수 포인터를 대체하는 키워드)
1. 사용법
- 람다 함수는 캡처(Capture), 인자(Parameter), 반환형(Return-Type), 바디(Body) 로 구성되어 있다.
- 캡처와 인자는 콤마(,)로 구분하여 여러 개 지정할 수 있다.
[capture] (parameter) -> return-type { body };
(1) 캡처(Capture)
- 캡처는 람다 함수에서 사용할 변수나 상수를 참조나 복사의 형태로 찍어오는 것이다.
- 전역 변수를 참조로 캡처할때는 [&], 복사로 캡처할때는 [=]를 사용한다.
- 지역 변수를 참조로 캡처할때는 [&변수명], 복사로 캡처할때는 [=변수명]을 사용한다.
[&]() { return; } // 모든 변수를 참조로 캡처
[=]() { return; } // 모든 변수를 복사로 캡처
[&var1, var2]() { return; } // var1은 참조, var2는 복사로 캡처
[=, &var1]() { return; } // var1만 참조로 캡처하고, 다른 변수는 복사로 캡처
[&, var2]() { return; } // var2만 복사로 캡처하고, 다른 변수는 참조로 캡처
- 복사로 캡처된 변수는 기본적으로 constexpr 타입으로 지정되어 값의 변경이 불가하다.
- mutable로 선언하면 값의 변경이 가능하다.
int var1{0};
[var1]() {
var1 = 999; // 에러!!! - var1은 constexpr 타입이므로 변경이 불가
}();
[var1]() mutable {
var1 = 999; // var1은 mutable로 선언되어 변경이 가능, 단 실제 값은 변하지 않음
std::cout << var1 << std::endl; // 999
}();
std::cout << var1 << std::endl; // 0
(2) 인자(Parameter)
- 일반 함수의 인자처럼 람다 함수에서 사용할 인자를 지정한다.
[](int a) -> int { return a; } // 1개의 인자를 설정
[](int a, int b) -> int { return (a+b); } // 2개의 인자를 설정
(3) 반환형(Return-Type)
- 람다 함수의 실행 결과를 반환할 반환 타입을 지정한다.
(4) 바디(Body)
- 람다 함수에서 수행할 작업을 기술한다.
2. 사용 예제
#include <iostream>
#include <functional>
int main()
{
// 간단한 람다 함수
[]() {
std::cout << "Simple Lamda Function" << std::endl;
}();
// 인자 2개를 더해서 sum에 저장하고, 더한 값을 반환하는 람다 함수
int sum{0};
// std::function 에 람다 함수를 정의
std::function<int(int,int)> fSum{[&sum](int a, int b) -> int {
sum = a + b;
return sum;
}};
std::cout << fSum(10, 20) << std::endl; // 30
std::cout << sum << std::endl; // 30
return 0;
}
3. 사용 예제 (클래스에서 사용)
#include <iostream>
#include <functional>
#include <string>
class Person
{
public:
Person(std::string&& pName, int pAge, std::function<std::string(std::string&, int)>&& pFunc)
: mName(std::move(pName))
, mAge(pAge)
, mTagFunc(std::move(pFunc)) // 람다 함수로 전달받은 임시 함수(r-value)를 std::move를 사용해 저장
{
// 출력 람다 함수에서 클래스의 멤버 변수를 사용하기 위해 this를 캡처한다.
mPrintFunc = [this]() {
std::cout << "Name: " << mName << ", Age: " << mAge
<< ", Tag: " << mTag << std::endl;
};
}
void executeTagFunc()
{
// 태그 생성 람다 함수 호출
mTag = mTagFunc(mName, mAge);
}
void executePrintFunc()
{
// Person 정보 출력 람다 함수 호출
mPrintFunc();
}
private:
std::function<std::string(std::string&, int)> mTagFunc{};
std::function<void()> mPrintFunc{};
std::string mName{};
std::string mTag{};
int mAge{0};
};
int main()
{
// 객체 생성시 [이름], [나이], [태그 생성 함수]를 인자로 받음
Person ps("Simson", 44, [](std::string& pName, int pAge) -> std::string {
return std::string(pName + "-" + std::to_string(pAge));
});
ps.executeTagFunc();
ps.executePrintFunc();
return 0;
}
반응형
'Programming Language > C++11' 카테고리의 다른 글
[c++11] std::tuple - 두 개 이상의 변수나 객체를 한번에 전달 (0) | 2024.07.02 |
---|---|
[c++11] std::pair - 두 개의 변수나 객체를 한번에 전달 (0) | 2024.07.02 |
[c++11] std::function - 함수 포인터를 대체하는 키워드 (9) | 2024.06.25 |
[c++11] Smart Pointer (std::unique_ptr, std::shared_ptr) (21) | 2024.06.24 |
[c++11] std::atomic - 원자성을 보장해야 할 변수 정의 (26) | 2024.06.21 |