🔖 INDEX
자동 형식 추론 (auto)
auto는 C++11에서 도입된 키워드로, 변수의 타입을 컴파일러가 자동으로 추론하게 하는 기능입니다. 즉, 개발자는 변수의 정확한 타입을 명시하지 않고 auto 키워드를 사용하여 컴파일러에게 타입 추론을 맡길 수 있습니다.
auto 사용 예
auto i = 42; // int
auto d = 3.14; // double
auto s = "hello"; // const char*
auto v = std::vector<int>{1, 2, 3}; // std::vector<int>
이처럼 auto는 변수의 초기화식을 기반으로 해당 변수의 타입을 추론합니다.
auto의 장점
- 가독성 향상: 복잡한 타입명을 반복적으로 작성할 필요가 없어 코드가 더 간결하고 가독성이 향상됩니다.
- 타입 안정성: 컴파일러가 타입을 추론하기 때문에 실수로 잘못된 타입을 지정하는 오류를 방지할 수 있습니다.
- 코드 유지보수: 코드의 일부분에 변경이 생겨도 auto를 사용한 부분은 자동으로 타입이 조정되므로 유지보수가 용이합니다.
auto의 주의사항
- 명확성: auto는 코드의 간결성을 제공하지만, 어떤 타입을 의미하는지 명확히 알 수 없을 때도 있습니다. 따라서 사용 시 주의가 필요합니다.
- 초기화 필요: auto를 사용한 변수는 반드시 초기화 되어야 합니다. 그렇지 않으면 컴파일러는 타입을 추론할 수 없습니다.
범위 기반 for 루프
C++11부터는 컨테이너나 배열의 모든 요소를 쉽게 순회할 수 있는 '범위 기반 for 루프'라는 편리한 문법이 도입되었습니다. 전통적인 for 루프는 인덱스나 반복자를 이용하여 컨테이너의 요소를 순회하는 데 사용되었습니다. 반면, 범위 기반 for 루프는 컨테이너의 시작부터 끝까지 모든 요소를 자동으로 순회하면서 각 요소에 접근할 수 있게 해주는 문법입니다.
범위 기반 for 루프 사용 예
std::vector<int> vec = {1, 2, 3, 4, 5};
for(auto num : vec) {
std::cout << num << " ";
}
int arr[] = {10, 20, 30, 40};
for(auto val : arr) {
std::cout << val << " ";
}
범위 기반 for 루프의 장점
- 간결성: 인덱스나 반복자를 사용하는 전통적인 for 루프에 비해 코드가 훨씬 간결해집니다.
- 가독성 향상: 코드의 의도가 명확하게 드러나므로 가독성이 향상됩니다.
- 오류 감소: 인덱스나 반복자를 잘못 사용하는 실수를 줄일 수 있습니다.
범위 기반 for 루프의 주의사항
1. 범위 기반 for 루프의 기본적인 사용은 읽기 전용입니다. 만약 컨테이너의 요소를 수정하고 싶다면, 참조 형식을 사용해야 합니다.
for(auto &num : vec) { // 요소를 참조로 받아옴
num *= 2; // vec의 모든 요소를 2배로 만듭니다.
}
2. 컨테이너 변경 주의: 루프 내에서 현재 순회 중인 컨테이너의 크기나 구조를 변경하는 연산을 주의해야 합니다
nullptr
C++11에서 도입된 nullptr는 포인터 리터럴의 새로운 타입입니다. nullptr는 모든 포인터 타입에 대해 사용할 수 있는 리터럴이며, 포인터가 가리키는 주소가 없음을 나타내기 위해 사용됩니다. 이는 C++에서 전통적으로 사용되던 NULL이나 숫자 0을 대체하기 위해 도입되었습니다.
nullptr의 도입 배경
전통적인 C++에서는 포인터를 초기화하지 않을 때, NULL이나 0을 사용하곤 했습니다. 하지만 이러한 방식은 다음과 같은 문제점들을 가지고 있었습니다:
- 타입 안정성: NULL은 매크로로 정의되어 있어 실제로는 정수 타입입니다. 따라서 함수 오버로딩 등의 상황에서 예기치 않은 동작을 일으킬 수 있습니다.
- 가독성: 0을 사용할 경우, 포인터의 초기화와 정수 0 사이의 구분이 불명확해질 수 있습니다.
이러한 문제점들을 해결하기 위해 C++11에서는 명시적으로 포인터를 위한 nullptr를 도입하였습니다.
nullptr 사용 예
int* pi = nullptr; // 정수 포인터 초기화
void* pv = nullptr; // void 포인터 초기화
void func(int* ptr) {
if (ptr == nullptr) {
std::cout << "Pointer is null!" << std::endl;
} else {
std::cout << "Pointer is not null!" << std::endl;
}
}
func(pi); // 출력: Pointer is null!
nullptr 주의사항
- nullptr는 모든 포인터 타입과 호환될 수 있지만, 정수 타입과는 직접적으로 호환되지 않습니다. 따라서 정수 값으로의 변환을 시도할 때는 명시적인 캐스팅이 필요합니다.
- C++11 이전의 코드와의 호환성을 위해 NULL도 여전히 사용할 수 있습니다. 그러나 새로운 코드를 작성할 때는 nullptr의 사용을 권장합니다.
람다 식 (Lambda Expressions)
C++11에서 도입된 람다 식은 이름 없는 인라인 함수를 정의하는 문법입니다. 함수 포인터나 함수 객체를 요구하는 곳에 간단하게 함수의 동작을 정의하고 사용하게 해줍니다.
기본 문법
람다 식의 기본 문법은 다음과 같습니다:
[capture_clause](parameter_list) -> return_type { function_body }
- capture_clause: 외부 변수를 람다 함수 내부로 "캡쳐"하는 방법을 정의합니다.
- parameter_list: 함수의 매개변수 목록입니다.
- return_type: 반환 타입을 지정합니다. (자동 추론 가능하므로 생략 가능)
- function_body: 함수의 본문입니다.
람다 사용 예제
람다 식의 기본 문법은 다음과 같습니다:
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
int value = 3;
auto result = std::find_if(numbers.begin(), numbers.end(), [value](int num) {
return num > value;
});
if (result != numbers.end()) {
std::cout << *result << std::endl; // 4 출력
}
return 0;
}
캡쳐 모드
- []: 아무 것도 캡쳐하지 않습니다.
- [=]: 모든 외부 변수를 값으로 캡쳐합니다.
- [&]: 모든 외부 변수를 참조로 캡쳐합니다.
- [a, &b]: 변수 a는 값으로, b는 참조로 캡쳐합니다.
활용 방안
람다는 다음과 같은 경우에 효율적으로 활용될 수 있습니다:
- 알고리즘: STL 알고리즘에서 사용자 정의 동작을 정의할 때
- 이벤트 핸들러: 이벤트 반응 방식을 직접 지정할 때
- 임시 동작: 특정 동작을 일회성으로 정의하고 싶을 때
'프로그래밍 > C++' 카테고리의 다른 글
C++11 주요 업데이트 : override, final, std::thread, std::array (0) | 2023.09.30 |
---|---|
C++11 주요 업데이트 : Initializer Lists, decltype, Template Aliases (0) | 2023.09.30 |
C++의 메모리 관리 : 동적 할당, 스마트 포인터 (0) | 2023.09.29 |
C++ 함수 포인터 (Function Pointer) (0) | 2023.09.29 |
C++ 서식지정자(Format Specifier) (0) | 2023.09.27 |
댓글