250327 수업정리..(4w2)
Callable Types
호출 가능한 타입..
함수처럼 호출()할 수 있는 모~~든 것을 callable 이라고 함.
1. 함수 : 이름 있는 함수
2. 함수 포인터 : 함수 주소를 가리키는 포인터
3. 람다[] lambda : 이름 없는 즉석 함수
이것들 모두 () 연산자로 호출할 수 있기에.. callbale type 이라고 함
void*
이건.. 어떤 타입이든 가리킬 수 있는 일반적인 포인터임!!!
이건 함수 포인터가 아님... 그냥 타입이 없는 포인터!!!!!

이런식으로... int값을 반환하는 내림차순()이라는 함수안에 매개변수로
cosnt void* a, const void* b 가 들어가있음.
여기서 void*는 void라는 함수를 가리키는게 아니라... 저 void*는 어떠한 타입이든 가리키는 일반적인 포인터!!
또한... void*로 받아온 건.. 타입 정보가 없기에..
약간.... "어디에 뭐있는진 모르겠지만, 어쨌든 메모리 주소야~" 라고 하는 것임...
주소만 저장했으니, 그 주소에 있는 값이 int 인지 double 인지 모른다!!!
그러니까... int*를 통해 명시적으로 형변환을 해줘야 한다..!
함수포인터
함수포인터는.. 함수를 가리키는 포인터!

함수를 인자로 넣고 싶을 때... 또는 나중에 호출하고 싶을 때 사용

이런식으로... 정렬기준이라는 함수 포인터를 만들어서,
정렬기준이 내림차순이라는 함수를 가리키게 만들면, 그걸 qsort()에서는 인자로 사용가능함!!!!

함수포인터를 호출하는 방법... 그냥 함수 호출하듯이 해도 됨! 왜냐면 함수포인터는
callable type 이니까~~~~!!!!
[] 람다
일단.. 람다는 이름 없는 함수..! 근데 람다를 왜 쓰는가??를 답하자면..
한번만 쓸 짧은 함수를 이름없이 쓰기 위해~! 라고 할 수 있음...
람다 객체는 주로 스택에 생성된다..
람다는 값을 참조해오거나 복사해올 수 있다... 그건 [] <- 캡처 영역에 넣어주면됨..

복사는.. 람다 안에 값을 고정시킴 -> 값 변동X 위의 예시처럼.. x=20; 으로 x값을 바꿔줘도 lam1()에는 여전히 x=10으로 저장되어있다..
참조는.. 바깥 변수의 실시간 변화를 반영할 수 있음.. -> 값 변동O
x=20;을 해주니, lam2()의 값이 변하였다!
왜 람다 호출이 빠른가?


현재 오름차순.. 이라는 함수포인터를 호출하고 있다.. 이 과정 자체가 함수 오버헤드를 일으킴!

현재 정렬 방식을 템플릿 인자로 넘김.. 함수호출을 하지 않기에 빠른 것.. 인라인 기법을 사용함..
인라인이 뭐냐면
함수호출을 줄이기 위해, 함수 본문을 그대로 복사해 넣는 최적화 기법을 말한다..
[]라는 인라인을 사용해서 코드 안에 직접 넣어버렸다..! -> 그래서 빠른 것이다..
sort는 템플릿 함수라서.. 컴파일 때 마다 거기에 맞춰 함수 코드가 만들어짐..
람다는 컴파일 때 타입 전달,
함수 포인터는 런타임때 전달.. 즉 함수포인터는 함수 주소를 전달함.. 그래서 sort실행할 때 해당 함수를 호출해야함
이때 함수 본문을 알 수 없어서..(=인라인X) 진짜 런타임까지 뭐가 올지 모르기에 최적화가 안되는 것이다..
결론은....
비교연산을 함수호출없이 바로바로 처리가능하기에!! 인라인 최적화를 하기에! 더 빠른 것이다...!!!
ㄲㅡㅌ
'cpp(stl)' 카테고리의 다른 글
cpp9 STRING객체/list/vector/deque (1) | 2025.05.23 |
---|---|
cpp8(callable) (0) | 2025.04.11 |
cpp6(RAII/throw/unique_ptr) 4w1 (0) | 2025.04.08 |
cpp5(stream_iterator/vector로 파일읽기/structured binding/연산자오버로딩) (0) | 2025.03.27 |
cpp4(파일입출력/바이너리모드/저수준출력) (0) | 2025.03.19 |