본문 바로가기

스터디/C++

Lambda Expression

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <vector>
#include <stack>
 
int main(int argc,char *argv[]){
    [] () {} ;
 
 
}
 
cs




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
 
 
 
 
struct Student
{
    std::string name;
    
    int kor;
    int math;
    int eng;
 
    double average;
};
 
using Student = struct Student;
 
 
bool Compare(Student& a,Student& b);
 
 
int main(int argc,char *argv[]){
    
    std::vector<Student> vStudent = {
        {"SonGun",90,80,70},
        {"Hyunwoo",100,100,100},
        {"YoungHoo",100,90,80}        
        
    };
 
    std::sort(vStudent.begin(),vStudent.end(),Compare);
 
    for (auto& v : vStudent){
        std::cout << v.name << std::endl;
    }
    
 
 
}
 
 
bool Compare(Student& a, Student& b){
    return (a.kor + a.math + a.eng) < (b.kor + b.math + b.eng);
}
cs



두번째 코드 (바로 위에 있는 코드) 에서 Compare 함수는 한 번 사용되는 함수이다.


그래서 이 때, lambda 식을 사용한다. 

lambda 식을 사용하면 함수가 필요 없어진다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
 
 
 
 
struct Student
{
    std::string name;
    
    int kor;
    int math;
    int eng;
 
    double average;
};
 
using Student = struct Student;
 
 
bool Compare(Student& a,Student& b);
 
 
int main(int argc,char *argv[]){
    
    std::vector<Student> vStudent = {
        {"SonGun",58,55,95},
        {"Hyunwoo",100,100,100},
        {"YoungHoo",78,30,72}        
        
    };
 
    std::sort(vStudent.begin(),vStudent.end(),[](Student& a, Student& b) {
        return (a.kor + a.math + a.eng) < (b.kor + b.math + b.eng);
    });
 
    for (auto& v : vStudent){
        std::cout << v.name << std::endl;
    }
    
 
 
}
 
/*
// Don't Need!!
bool Compare(Student& a, Student& b){
    return (a.kor + a.math + a.eng) < (b.kor + b.math + b.eng);
}
*/
cs


이렇게 람다식을 사용해서, Compare 함수를 사용할 필요가 없어진다.

람다 식은 []() {} 으로 이루어져 있는데,

[]  --> Capture clause

() --> 인자값을 적어준다.

{} --> 함수 코드 내용에 해당되는 코드를 적는다.

(아래 참고)

1
[x](int args) { function code... };
cs



What is Capture Clause?

변수 명을 적어주었을 때, 변수가 그대로 복사된다. (Pass By Value) 

1
2
3
int x;
 
[x](int args) { function code... };
cs

이 때 람다식 내부의 x와 외부의 x는 완벽하게 다르다. (복사됨)


= 을 적어주었을 떄 모든 변수를 value 로 넘기겠다는 뜻.


& 을 적어주었을 때 Pass by value 대신 Pass By Reference


this  도 사용가능하다!!


주의!!

Capture default = & 를 하였더라도 body 에서 사용하지 않았다면 capture 는 일어나지 않는다!!!



() --> 인자값을 적어준다  에서,

Return type deduction 을 수행한다.

(리턴 타입 추론)

C++ 11 에서는 return 이 한번만 나타나거나, 혹은 없는 경우만 자동 타입 추론 됨.

C++ 14 에서는 모든 반환 형이 동일할 경우 자동 타입 추론 됨.



mutable

- "돌연변이" 라는 의미로 const 형 함수에서 mutable 형태의 변수는 값 변경이 가능함.

--> const 함수에서 값 변경을 하고 싶을 때 mutable 변수를 사용함.


lambda 의 기본 call operator 는 const-by-value 이다.

mutable 을 사용하면 const 를 제외하여 value(copy) capture 한 내용 수정 가능.


exception

throw() 혹은 noexcept 와 같은 형태 가능

Exception throw 시 terminate 수행

C++ 03의 throw(..) 는 사용하지 않도록


noexcept 는 성능 상의 이점이 있음.

(컴파일러에게 많은 정보를 줄수록, 최적화가 될 수 있는 여지를 많이 주는 것)




Lambda Expression

- constructor 와 call operator 를 가지고 있는 새로운 class 를 생성

- Capture 수문에 따라 member variable 이 추가됨

- Function object (functor) 와 거의 유사함.

- Capture clause 가 없는 Lambda Expression

- 사용 빈도가 매우 적은 (한 번) 함수 작성을 막기 위해 사용함.