**try, catch

int main()
{
	int iNum1 = 0, iNum2 = 0;
	cin>>iNum1>>iNum2;
	try
	{
		if(!iNum2) throw iNum2;
		cout<<iNum/iNum2;
	}
	catch(int)
	{
		cout<<"Wrong"<<endl;
	}
}

**auto

class Obj
{
	//
}
 
auto a = true; //bool
auto b = 'A';  //char
auto c = "abc";//const char *
auto d = 10;   //int
auto e = 4.3f; //float
 
auto f = new Obj;//Obj*
  • 주로 STL 컨테이너와 같이 사용됨
vector<int> vecInt;
 
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(2);
 
//auto가 저절로 자료형을 추론함
auto iter = vecInt.begin()

**범위 기반 for문

  • C#, java에서 먼저 제공,
  • 제공하는 자료의 개수 만큼만 for문이 동작
  • 컨테이너의 값이 복사되어서 전달됨
  • &를 사용하여 컨테이너 원소 값에 직접 접근 할 수 있음
int iArr[5] = {1,2,3,4,5};
 
for(int i: iArr)
{
	cout << i << endl;
}
 
for(auto i : vecInt)   //vector의 원래 원소 변경 x
{
	i+=1;
}
 
for(auto& i : vecInt)
{
	i+=1;
}
 
map<int,int> mapInt;
 
 
for(auto i : mapInt)  //i는 pair 객체
{
	cout << i.first << i.second << endl;
}

**유니폼 초기화

  • 중괄호 식을 이용한 초기화 문법을 간략하게 표현하는 방법
struct tagInfo
{
	int x;
	int y;
}
class CObj
{
public:
	CObj(tagInfo _tInfo)m_tInfo(_tInfo);
 
	void Render();
	void getData() {return tagInfo{10,20}}
private:
	tagInfo m_tInfo;
}
 
int iArr[5]{1,2,3,4,5};
 
tagInfo tInfo{10, 20};
 
CObj obj({10,20})  //적절한 생성자가 있다면 가능!
 
vector<int> vecInt{1,2,3,4,5}; 
 
map<int,int> mapInt{{1,100}, {2,200}, {3,300}};

**람다식

  • 함수 객체를 대체하기 위한 문법
  • 이름이 없는 inline 함수
  • [](){} 형태
  • [] : 람다 소개자, 캡처절. 컴파일러가 람다식인 것을 인지
  • () : 파라미터 지정자. 일반 함수의 파라미터와 동일
  • {}: 람다 몸체. 일반 함수의 몸체와 동일
  • 이름이 없는 함수이기 때문에 오버로딩이라는 개념이 없음.
[](){cout<<"hello world"}  //그냥 사용시 호출 x
[](){cout<<"hello world"}()//호출 연산자를 사용해야 함
 
[](int i){cout << i << endl;}(100) //실행 100
 
//묵시적 반환
int iRes=[](int Dst, int Src){return Dst+Src}(10,20)
//명시적 반환
int iRes=[](int Dst, int Src)->int{return Dst+Src}(10,20);

**캡처절

  • 함수 외부의 변수들을 람다식 내부에서 사용하는 것
  • 복사 방식 : 사본을 만들어서 값만 가져오는 행위(const 성격)
  • 참조 방식 : 원본을 참조하는 행위
  • 사본의 const 성격을 제거 하기 위해서 mutable 키워드 사용 가능
  • static 변수, 전역변수, 클래스의 멤버 변수는 캡처 불가(데이터 영역)
 

**조건자로서의 람다식

//예제1
vector<int>		vecInt{ 10, 20, 30, 40, 50 };
for_each(vecInt.begin(), vecInt.end(), 
 [](int n) 
 {
	 cout << n << endl; 
 });
 
//예제2
vector<int>	vecInt{ 10, 20, 33, 40, 50 };
	
auto iter = find_if(vecInt.begin(), vecInt.end(), 
 [](int n)->bool
 { 
	 return 0 != (n % 2);
 });
 
cout << *iter << endl;
 
//예제3
 
 int iEvenSum(0), iOddSum(0);
 
 vector<int> vecInt{ 1,2,3,4,5 };
 
 for_each(vecInt.begin(), vecInt.end(), [&iEvenSum, &iOddSum](int n) 
 	{
 		if (0 == n % 2)
 			iEvenSum += n;
 
 		else
 			iOddSum += n;
 
 	});
 
 cout << iEvenSum << endl;
 cout << iOddSum << endl;

**R-Value 레퍼런스

class CObj
{
public:
	CObj():m_iX(0),m_iY(0){}
	CObj(int &X, int &Y):m_iX(X), m_iY(Y){}
private:
	int m_iX;
	int m_iY;
}
 
CObj* Create(int& X, int &Y)
{
	return new CObj(X,Y);
}
 
CObj* Create2(int&& X, int&& Y)  //r-value 레퍼런스를 매개변수로 받음
{
	return new CObj(X,Y);
}
 
int main()
{
    //불가능 !! r-value를 l-value를 받는 함수에 전달 할 수 없음
	CObj* ptr = Create(10,20) 
	//가능!
	CObj* ptr2 = Create2(10,20)
}

**이동 생성자

  • 원본을 사본으로 이전 시켜 생성하는 생성자, 명시적인 구현이 있어야 함
  • 복사 생성보다 속도가 월등히 빠름
class CMyClass
{
private:
	int* m_pArr;
	int m_iSize;
public:
	CMyClass(int iSize):m_iSize(iSize), m_pArr(new int[iSize]){}
	CMyClass(const CMyClass& _ref)
	{
		m_iSize=_ref.m_iSize;
		m_pArr = new int[_ref.m_iSize];
		memcpy(//메모리 복사)
	}
	CMyClass(CMyClass&& _ref)   //이동 생성자
	{
		m_iSize = _ref.m_iSize;
		m_pArr = _ref.m_pArr;
		_ref.m_pArr = nullptr  //소유권 이전
	}
}
 
int main()
{
	CMyClass test1(10000); 
	CMyClass test2(test1);  //복사 생성자 호출! 
 
	CMyClass test3(std::move(test1)); 
	//move() : r-value로 캐스팅하는 함수, 이동 생성자 호출!
}