본문 바로가기

C++

[TIL 32장] C++ 11 주요 함수 - 유니폼 초기화, auto, 범위 지정 for문, 람다식, try-catch문

오늘의 TIL 목차 (22. 09. 22)

 

  • 유니폼 초기화
  • auto
  • 범위 지정 for문
  • 람다식
  • try-catch문

 

C++ 11 주요함수


[ 유니폼 초기화 ]

: 초기화 방식의 일부, 객체를 생성하는 단계에서 () 대신 {}를 이용하여 값을 초기화할수 있다.

[ 초기화 방법 ]
1. int iA = 10; // C 시절의 초기화, 비추
2. int iA(10); // C++ 시절의 초기화
3. int iA{10}; // C++ 11, 유니폼 초기화

 

■ 기능 / 주의

  • 구조체를 초기화할 때 주로 사용, 클래스도 유니폼 초기화 가능하나 잘 사용하지 않는다.
  • 유니폼 초기화로 클래스의 멤버 값을 바꿔주고 싶으면 인자 값이 있는 생성자를 만들어줘야 한다.

■ 예시

struct tInfo
{
	char* sName;
	int iNum;
	float fNum;
};

void main(void)
{
	tInfo tMe[2]{ "다인", 1, 10.f, "시우", 2, 20.f };

	for (auto& i : tMe)
		cout << i.sName << "\t" << i.iNum << "\t" << i.fNum << endl;
}
출력 결과:
다인	1	10
시우	2	20

[ auto ]

: 컴파일러가 할당되는 값에 따라 알아서 자료형을 지정해주는 키워드, 자료형 위치에 대신 사용

: 선언된 변수의 초기화 식을 사용하여 해당 형식을 추론하도록 컴파일러에 지시한다. 즉, auto 키워드를 사용하면 초깃값의 형식에 맟춰 선언하는 인스턴스(변수)의 형식이 '자동'으로 결정 - 이것을 '타입 추론' 이라고 한다.

void main() {
	auto i = 10; // auto는 int
    	auto f = 1.f; // auto는 float
    	auto d = 5.5; // double, 일반 소수는 double로 인식
    	auto c = "다인"; // "다인"은 컴파일러 입장에서 주소상수라 cosnt char* ( 4byte )
	//auto array[5]{1, 2, 3, 4,10}; // 배열은 auto 불가능
}

■ 기능 / 주의

  • STL에서 반복자 선언할 때 주로 사용됨, auto로 반복자 선언 시 선언과 동시에 초기화를 해줘야 한다.
  • 템플릿 클래스/함수를 사용할 때 <>안에 auto 사용 불가, 명시적으로 자료형을 선언해줘야 하기 때문이다.

[ 범위 기반 for문 ]

: 알아서 처음부터 끝까지 순회해주는 반복문

for ( 원소자료형 변수명 : 순회할 배열/컨테이너 ) { 몸체 };

Ex.
int iArray[5]{1,2,3}; // 유니폼 초기화, 배열 크기는 5이므로 나머지는 0으로 채워짐
for( auto& i ; iArray ) // auto는 원소 타입인 int형으로 결정됨
	cout << i << "\t";

출력 결과 : 1	2	3	0	0

■ 기능 / 주의

  • 왼쪽은 순회할 배열/컨테이너의 원소 자료형이다. ( 컨테이너를 순회한다하더라도 iterator가 아님 )
  • 매개변수의 왼쪽, 즉 원소 부분은 복사되어진 값이기 때문에 원본값을 변경하고 싶다면 &를 붙여야 한다.
    - 레퍼런스를 붙이지 않은 원소는 사본, 값을 바꾼다면 for문 안에서만 변경되고 원본값은 변경되지 않음
  • 인덱스를 따로 지정할 수 없다. 즉 처음부터 끝까지 순회하는 경우에만 편리하다.

 

C++ 11 주요함수 - 람다식


[ 람다식 ]

: 람다식은 이름 없는 '무명 함수'이며 inline이 일어난다, 함수 객체를 계승하고 발전시킨 문법

: 함수의 기능을 메모리를 할당하지 않고 해당 라인에 바로 적어 사용 가능한 식

[](매개변수)->반환타입 {몸체}; // 이거 자체가 함수이자 함수 이름

람다식
[] : '람다 소개자', 컴파일러가 람다식이라는 것을 인지할 수 있음
() : '파라미터 지정자', 일반 함수의 파라미터와 같은 의미
{} : '람다 몸체', 일반 함수의 몸체와 같은 의미
만약 입력 받은 값에 10을 더한 값을 출력하는 함수를 람다식으로 표현한다면
[]->void (int _iA) { cout << iA+10 << endl; return; }(5);

=> 끝에 ()는 함수명(); 로 호출하듯이 호출해준 것
=> 매개변수가 없다면 람다식 호출 시 ()만 적으면 됨

 

■ 기능 / 주의

  • 람다식도 자료형 타입이 존재하여 템플릿 T에 넘겨줄 수 있으나 우리가 자료형을 표현할 이름은 없다.
    - 캡처절이 없는 [] 람다식 자체는 auto로 받거나 함수 포인터로 변환하여 받을 수 있다.
  • 람다식 자체가 함수의 이름(주소)이다.
  • 람다식은 값으로 캡처 시 캡처한 변수를 자동으로 const화 한다.
  • const 성격을 벗겨내기 위해 mutable을 사용하면 복사본을 대상으로 값 변경은 가능하지만 원본 값 변경은 안된다.
  • 원본 값 변경을 위해서는 레퍼런스로 캡처하면 된다.

■ 람다식 캡처절

■ 예시

void main(void)
{
	int i = 0;
	string sName = "다인";
	int iNum = 0, iHome = 10;

	i = [i, &iNum, iHome](int _iA)->int { cout << i + 1 << endl;   iNum += iHome;  return iNum; }(5);
    // 끝에 (5)는 람다식(함수 이름 자체)에 매개변수 5를 넣어 호출한 것
	cout << i << endl;
	cout << iNum << endl;
}

출력 결과 : 
5	5 // 레퍼런스 캡처로 인해 실제 iNum값도 변경됨

try-catch문


[ try-catch문 ]

: try-catch안의 throw를 만나면 밑의 명령문을 무시하고 바로 catch문으로 이동, to_string()은 문자열 변환