C++11 버전에 람다 함수라는 표현식이 등장합니다. 이는 여러 예제에서 확인할 수 있는데 Qt를 하신다면 QML Quick Application Project를 생성했을 때 main.cpp에서도 확인할 수 있습니다.
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}
, Qt::QueuedConnection);
람다 함수는 함수 호출 과정을 생략해 시간을 절약하고 적응하면 코드의 가독성을 높일 수 있는 함수 표현 방식입니다. 람다함수는 함수 이름이 없기 때문에 익명 함수라고도 합니다.
람다 함수의 문법은 아래와 같습니다.
먼저 대괄호에 둘러싸인 캡처입니다. 람다 함수에서 사용하고자 하는 외부 변수를 여기에 명시합니다. 함수 내에서 그 변수를 사용하기 위해서입니다.
int main() {
int nHeight = 170;
[](int nWeight) { cout << "Height = " << nHeight << "Weight = " << nWeight; } (50);
return 0;
}
위 코드에서 람다 함수 내부에서 main 안에 있는 Height를 사용할 때 오류가 발생합니다.
이렇게 람다 외부에 있는 값을 사용하기 위해서는 캡처를 이용해야 합니다. 캡처에는 [=]와 [&]이 존재합니다. [=]는 외부 변수를 값으로 전달받고 [&]는 참조로 전달받습니다.
[=]를 통해 전달받는 외부 변수는 값을 변경할 수 없습니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
[=](int nWeight) {
cout << "Height = " << nHeight << " Weight = " << nWeight << endl;
nHeight = 200;
} (50);
cout << "Height = " << nHeight << endl;
return 0;
}
전달받은 값을 변경하기 위해서는 [&] 캡처를 사용해야 합니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
[&](int nWeight) {
cout << "Height = " << nHeight << " Weight = " << nWeight << endl;
nHeight = 200;
} (50);
cout << "Height = " << nHeight << endl;
return 0;
}
캡처를 더 세세하게 설정이 가능합니다. 전달 방식과 변수를 같이 기입하여 세밀하게 설정할 수 있습니다.
- [&a] : 외부 변수 a만 참조로 전달받아 사용합니다. 다른 외부변수는 사용 불가합니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
int nAge = 20;
[&nHeight](int nWeight) {
cout << "Height = " << nHeight << " Weight = " << nWeight << endl;
cout << "Age = " << nAge;
nHeight = 200;
} (50);
cout << "Height = " << nHeight << endl;
return 0;
}
- [=, &a] : 외부 변수 모두 값으로 전달받아 사용하지만 a 변수만 참조로 전달받아 사용합니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
int nAge = 20;
[=, &nHeight](int nWeight) {
cout << "Height = " << nHeight << " Weight = " << nWeight << endl;
cout << "Age = " << nAge << endl;
nHeight = 200;
} (50);
cout << "Height = " << nHeight << endl;
return 0;
}
- [&, a] : 외부 변수 모두 참조 값으로 전달받아 사용하지만 a 변수만 값으로 전달받아 사용합니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
int nAge = 20;
[&, nHeight](int nWeight) {
cout << "Height = " << nHeight << " Weight = " << nWeight << endl;
cout << "Age = " << nAge << endl;
nHeight = 200;
} (50);
cout << "Height = " << nHeight << endl;
return 0;
}
다음은 매개변수입니다. 매개변수는 기존 함수 선언과 마찬가지로 생략이 가능하며 사용하지 않을 경우에는 괄호 자체도 넣지 않아도 무관합니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
[&] {
cout << "Height = " << nHeight << endl;
nHeight = 200;
} ();
cout << "Height = " << nHeight << endl;
return 0;
}
다음은 mutable 속성입니다. 캡처를 값에 의한 전달일 때 오류가 나지 않게 해 줍니다. 하지만 결국 값에 의한 전달이기 때문에 람다 내부에서 값을 변경해도 외부에서는 그대로인 것을 확인할 수 있습니다.
#include <iostream>
using namespace std;
int main() {
int nHeight = 170;
[=](int nWeight) mutable {
cout << "Height = " << nHeight << " Weight = " << nWeight << endl;
nHeight = 200;
} (50);
cout << "Height = " << nHeight << endl;
return 0;
}
throw는 예외 처리 관련 키워드입니다. 해당 키워드가 없어도 상관없습니다.
#include <iostream>
using namespace std;
int main() {
int a = 5;
[=] (int nDiv) throw() {
try {
if ( nDiv == 0 ) {
throw 0;
}
cout << a/nDiv << endl;
}
catch (int e) {
cout << "Exception";
}
} (0);
return 0;
}
다음으로 반환형입니다. 기본적으로 람다 함수의 반환형은 void고 return을 사용하기 위해서는 반환형을 지정해야 합니다. 만약 따로 지정 안 하고 return 시에는 return에 맞춰 반환형이 결정되고 반환형을 지정했을 경우에 그에 맞춰 변경됩니다.
#include <iostream>
using namespace std;
int main() {
int a = 63;
cout << [=] (int nData) {
int nSum = a + nData;
return nSum;
} (0) << endl;
cout << [=] (int nData)->char {
int nSum = a + nData;
return nSum;
} (0) << endl;
return 0;
}
람다 함수는 아래와 같이도 사용할 수 있습니다. sort 함수 같이 함수를 인자로 넘기는 경우에 함수 자리에 람다 함수를 사용할 수 있습니다. auto 키워드를 이용해서 람다 함수를 변수로 지정하여 사용할 수 있습니다.
#include <iostream>
#include <algorithm>
using namespace std;
void printArr(int pArr[]) {
for(int i=0;i<10;i++) {
cout << pArr[i] << " ";
} cout << endl;
}
int main() {
int arr[10] = {3,8,19,1,4,22,3,24,51,29};
printArr(arr);
sort(arr, arr+10);
printArr(arr);
sort(arr, arr+10, [](int a, int b) { return a > b; });
printArr(arr);
sort(arr, arr+10);
printArr(arr);
auto des = [](int a, int b) { return a > b; };
sort(arr, arr+10, des);
printArr(arr);
return 0;
}
'Programming > C++' 카테고리의 다른 글
[C++] std::forward_list, std::list (0) | 2023.07.18 |
---|---|
[C++] std::array, std::vector (0) | 2023.07.12 |
[Effective C++] 4. 설계 및 선언 (0) | 2022.11.14 |
[Effective C++] 3. 자원 관리 (0) | 2022.11.07 |
[Effective C++] 2. 생성자, 소멸자 및 대입 연산자 (4) | 2022.10.31 |