728x90
황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!
https://search.shopping.naver.com/book/catalog/32436115747
auto를 이용한 쉬운 변수 선언
- auto 키워드는 C++11 표준부터 의미가 수정되어, 변수 선언문으로부터 변수의 타입을 추론하여 결정하도록 지시
- auto는 복잡한 형식의 변수 선언을 간소하게 해주며, 타입 선언의 오타나 번거로움을 줄이게 해준다
auto pi = 3.14; // 3.14가 실수이므로 pi는 double 타입으로 선언됨
auto n = 3; // 3이 정수이무로 n을 int로 선언
auto *p = &n // 변수 p는 int* 타입으로 선언
int n = 10;
int &ref = n; // ref는 int에 대한 참조 변수로 선언
auto ref2 = ref; // ref2는 int& 타입의 변수로 자동 선언
함수의 리턴 타입으로부터 추론하여 변수 타입 선언
int square(int x) { return x*x; }
...
auto ret = square(3); // 변수 ret는 int 타입으로 자동 선언
- 컴파일러는 square()의 리턴 타입이 int이므로 변수 ret의 타입을 int로 추론한다.
- square() 함수가 double을 리턴하는 함수로 수정되면 변수 ret의 타입도 double 타입으로 자동 결정
- auto는 코드의 수정에 따른 오류 가능성을 낮추는 효과가 있다.
아래 코드는auto를 사용하여 변수의 타입을 선언하는 다양한 예시이다.
#include <iostream>
#include <vector>
using namespace std;
int square(int x) { return x*x; }
int main() {
// 기본 타입 선언에 auto 활용
auto c = 'a'; // c는 char 타입으로 결정
auto pi = 3.14; // pi은 double 타입으로 결정
auto ten = 10; // ten은 int 타입으로 결정
auto *p = &ten; // 변수 p는 int* 타입으로 결정
cout << c << " " << pi << " " << ten << " " << *p << endl;
// 함수의 리턴 타입으로 추론
auto ret = square(3); // square() 함수의 리턴 타입이 int 이므로 ret는 int로 결정
cout << *p << " " << ret << endl;
vector<int> v = { 1,2,3,4,5 }; //벡터 v에 5개의 원소, 1,2,3,4,5 삽입
vector<int>::iterator it;
for (it = v.begin(); it != v.end(); it++)
cout << *it << " "; // 1 2 3 4 5 출력
cout << endl;
// 템플릿에 auto를 사용하여 복잡한 선언의 간소화
for (auto it = v.begin(); it != v.end(); it++)
cout << *it << " "; // 1 2 3 4 5 출력
}
/*
a 3.14 10 10
10 9
1 2 3 4 5
1 2 3 4 5
*/
람다 대수와 람다식
- 람다 대수에서 람다식(lambda expression)은 수학의 함수를 단순하게 표현하는 방법
f(x, y) = x + y
// 람다식
(x, y)-> x + y
- 수학에서 이름 없는 함수를 람다식이라고 한다. 괄호와 함께 x, y에 대입될 값을 지정하면 람다식의 계산이 이루어진다.
C++에서 람다식 선언
- 프로그래밍 세계에서 람다는 이름 없는 익명 함수(anonymous function)로, 람다식(lambda expression) 혹은 람다 함수로 불린다.
- 캡쳐 리스트, 매개 변수 리스트, 리턴 타입, 함수 바디의 4부분으로 구성된다.
/* 생략 가능 */
[ ] ( ) -> 리턴타입 { /* 함수 코드 작성 */ }
[](int x, int y) { cout << x + y; }; // 매개 변수 x, y의 합을 출력하는 람다 식
[](int x, int y) -> int { return x + y; }; // 매개 변수 x, y의 합을 리턴하는 람다 식
[](int x, int y) { cout << x+y; } (2, 3); // x에 2, y에 3을 대입하여 코드 실행
캡쳐 리스트
- 람다식의 외부에 선언된 변수(지역변수, 전역변수) 목록
표현 | 의미 |
[x] | 변수 x의 값 활용 |
[&x] | 참조 변수 x 활용 |
[=] | 모든 변수의 값 활용 |
[&] | 모든 참조 변수 활용 |
간단한 람다식 만들기
- 매개 변수 x, y의 합을 출력하는 람다식을 작성해보자.
#include <iostream>
using namespace std;
int main() {
// 람다 함수 선언과 동시에 호출(x=2, y=3 전달)
[](int x, int y) { cout << "합은 " << x + y; } (2, 3); // 5 출력
}
auto로 람다식 저장 및 호출
- 람다식의 형식은 컴파일러에만 알려져 있기에, 개발자가 람다식을 저장하는 변수를 직접 선언할 수 있다.
- auto를 이용하여 변수 love에 람다식을 저장하고, love()의 모양으로 람다식을 호출해보자.
#include <iostream>
#include <string>
using namespace std;
int main() {
auto love = [](string a, string b) {
cout << a << "보다 " << b << "가 좋아" << endl;
};
love("돈", "너"); // 람다식 호출
love("냉면", "만두"); // 람다식 호출
}
캡쳐 리스트와 리턴 타입을 가지는 람다식 만들기
- 람다식은 캡쳐 리스트를 이용하여 주변의 non-static 변수들(지역 변수나 멤버 변수)에 대해 값을 복사하여 받거나 참조를 활용할 수 잇다.
- 아래는 반지름이 r인 원의 면적을 리턴하는 람다식이다.
#include <iostream>
using namespace std;
int main() {
double pi = 3.14; // 지역 변수
auto calc = [pi](int r) -> double { return pi*r*r; }; // 반지름이 r인 원 면적을 리턴하는 람다 함수 작성
cout << "면적은 " << calc(3); // 람다식 호출. 28.26출력
}
- 아래는 캡쳐 리스트에 참조 활용하여 합을 외부에 저장하는 람다식이다.
#include <iostream>
using namespace std;
int main() {
int sum = 0; // 지역 변수
[&sum](int x, int y) { sum = x + y; } (2, 3); // 합 5를 지역변수 sum에 저장
cout << "합은 " << sum;
}
STL 템플릿에 람다식 활용
- STL 함수 for_each()를 이용하여 벡터의 모든 원소를 출력하는 예제이다.
#include <iostream>
#include <vector>
#include <algorithm> // for_each() 알고리즘 함수를 사용하기 위함
using namespace std;
void print(int n) {
cout << n << " ";
}
int main() {
vector<int> v = { 1, 2, 3, 4, 5 };
// for_each()는 벡터 v의 첫번째 원소부터 끝까지 검색하면서,
// 각 원소에 대해 print(int n) 호출. 매개 변수 n에 각 원소 값 전달
for_each(v.begin(), v.end(), print);
}
- 아래는 STL 함수 for_each()와 람다식을 이용하여 벡터의 모든 원소 출력
#include <iostream>
#include <vector>
#include <algorithm> // for_each() 알고리즘 함수를 사용하기 위함
using namespace std;
int main() {
vector<int> v = { 1, 2, 3, 4, 5 };
// for_each()는 벡터 v의 첫번째 원소부터 끝까지 검색하면서,
// 각 원소에 대해 3번째 매개변수인 람다식 호출. 매개변수 n에 각 원소 값 전달
for_each(v.begin(), v.end(), [](int n) { cout << n << " "; });
}
C++에서 람다식의 의미
C++ 프로그램 작성 시람다가 꼭 필요한 기능은 아니다. 다만 간단하고 짧게 최적화된 코드를 작성하는데 도움이 되며, 특별히 람다가 유용한 경우는 아래와 같다.
- 한 번만 호출하고 재사용하지 않기 때문에 함수에 이름을 붙일 필요가 없는 경우
- STL 알고리즘 함수의 매개 변수에 연산 코드를 넘기는 경우, 연산 코드를 익명의 람다식으로 작성
728x90
'Programming Language > C++' 카테고리의 다른 글
[C++] Vector with Cpp (1) | 2023.12.20 |
---|---|
[C++] Array with Cpp (1) | 2023.12.20 |
[C++] 표준 템플릿 라이브러리(STL) (0) | 2023.12.20 |
[C++] 제네릭 클래스 만들기 (1) | 2023.12.19 |
[C++] 다양한 제네릭 함수 만들기 (0) | 2023.12.19 |