what’s new in c++11
TRANSCRIPT
Blue Wind
백정상
WHAT’S NEW IN C++11
C++11
C++0x 로 알려짐2011 년 8 월에 표준으로 선정
CONTENTS
퍼포먼스 향상언어 사용성 강화언어 기능 강화c++ standard libraries 변경
퍼포먼스 향상불필요한 복사 / 생성 방지
R-VALUE REFERENCES
l-value
수식의 왼쪽에 있는 값일반적으로 대입되는 값
r-value
수식의 오른쪽에 있는 값일반적으로 대입하는 값
r-value reference
말 그래도 r-value 의 레퍼런스
왜 필요한가l-value reference 는 익숙히 사용하고 있었다
큰 데이터를 패러미터로 넘길 때 포인터보다 좀 더 안전하게 레퍼런스를 이용그럼 큰 데이터를 반환해야 할 때엔 ?
기존에는 컴파일러에서 최적화 해주는 수준으로 커버C++11 은 move semantic 을 도입
의미 없는 복사 / 생성을 최적화이를 위해서 반환해야 할 값의 레퍼런스 (r-value reference) 가 필요하다
예제std::vector<int> MakeVector() {
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
return vec;
}
std::vector<int> vec2 = MakeVector();
기존의 벡터 복사 생성자
vec
vec2
카피
새로 할당 된 메모리
R-VALUE REF 를 이용해 반환하는 과정
vec
vec3 null
R-VALUE REF 를 이용해 반환하는 과정
vec
vec3 null
이를 위해서C++11 은 이를 위해 두 가지 방식의 생성자를 지원
copy constructor
vector::vector(const vector<T>&v)
move constructor
vector::vector(vector<T>&& v)
대입 연산자도 비슷하게 두 가지를 지원
변수에서 R-VALUE 를 얻어야 할 때std::move() 를 사용해서 r-value 를 전달
class A {
A(A&& a) {
this->s = std::move(a.s);
}
private:
HugeBigObj s;
}
GENERALIZED CONSTANT EXPRESSIONS
기존에는 상수 연산이 없고 상수만 사용할 수 있었음코드 내에 잦은 상수연산은 컴파일러 퍼포먼스를 저하시켰음C++11 에는 상수 연산 키워드가 추가
int get_five() {return 5;}
int some_value[get_five() + 7]; // 컴파일 에러
constexpr int get_five() {return 5;}
int some_value[get_five() + 7]; // 12 개의 정수 배열이 만들어짐
INITIALIZER LIST
POD 나 스탠다드 컨테이너의 초기 변수를 리스트 형태로 전달 가능
std::vector<std::string> v = {“aaa”, “bbb”, “ccc”, “ddd”};
std::vector<std::string> v({“aaa”, “bbb”, “ccc”, “ccc”});
std::vector<std::string> v{“aaa”, “bbb”, “ccc”, “ddd”}; // Uniform initialization
UNIFORM INITIALIZATION모든 초기화 과정이 {var1, var2, … varn} 형태로 통합하여 사용이 가능
struct BasicStruct {
int x;
double y;
};
struct AltStruct {
AltStruct(int x, double y) : x_{x}, y_{y} {}
private:
int x_;
double y_;
};
BasicStruct var1{5, 3.2};
AltStruct var2{2, 4.3};
언어 사용성 강화불편했던 부분을 개선
TYPE INFERENCE
타입을 추론해서 선언이 가능
auto itr = m_map.find(10); //std::map<int, string>::iterator itr = m_map.find(10);
auto intValue = 5;
auto fValue = 5.0f;
auto 로 선언된 변수랑 같은 타입으로 선언하는 법const decltype(itr) end = m_map.end();
decltype(intValue) intValue2 = 10;
RANGE-BASED FOR LOOP
모든 시퀀스 컨테이너의 range 에 따라 아이템 순회가 가능해짐
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
x *= 2;
}
std::vector<int> numList = {1,2,3,4,5};
for (int &num : numList) {
cout << “num: “ << num * 2;
}
LAMBDA FUNCTIONS
[capture](parameters)->return-type{body}
간단한 익명 함수 처리가 가능해짐다양한 방식으로 사용이 가능CPS 코딩이 편해짐자세한 용례는 http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B 참고
LAMBDA 예제std::vector<int> some_list{ 1, 2, 3, 4, 5 };
int total = 0;
std::for_each(begin(some_list), end(some_list), [&total](int x) {
total += x;
});
OBJECT CONSTRUCTION IMPROVEMENTS
생성자에서 다른 생성자를 호출 가능해짐
class SomeType {
int number;
public:
SomeType(int new_number) : number(new_number) {}
SomeType() : SomeType(42) {}
};
OBJECT CONSTRUCTION IMPROVEMENTS
베이스 클래스 생성자 상속이 가능하고 어떤 생성자를 상속받을지 설정 가능class BaseClass {
public:
BaseClass(int value);
};
class DerivedClass : public BaseClass {
public:
using BaseClass::BaseClass;
};
EXPLICIT OVERRIDE AND FINAL
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int);
};
실수로 시그니처가 달라지면 virtual function 이 2 개 만들어지는 문제가 있었음
EXPLICIT OVERRIDE AND FINAL
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int) override; // 베이스 클래스와 시그니처가 맞지 않으면 에러를 표시};
걍 오버라이드 할 때엔 무조건 뒤에 붙이시면 됩니다
EXPLICIT OVERRIDE AND FINAL
final 키워드로 상속이나 오버라이드를 더 이상 못하게 막을 수 있음struct Base1 final { };
struct Derived1 : Base1 { }; // Base1 클래스가 final 선언되었으므로 에러
struct Base2 {
virtual void f() final;
};
struct Derived2 : Base2 {
void f(); // 가상함수 Base2::f 가 final 처리 되었으므로 에러};
NULL POINTER CONSTANT
nullptr 상수가 만들어짐
char *pc = nullptr; //OK
bool b = nullptr //OK. b is false
int a = nullptr; //error
STRONGLY TYPED ENUMERATIONS
enum 에 이름과 타입 설정이 불가능해서 예전엔 이런 꼼수를 썼음namespace Enumeration {
enum {
A,
B,
C
}
typedef int type;
}
Enumeration::type a = Enumeration::A;
STRONGLY TYPED ENUMERATIONS
이젠 타입과 이름 설정이 가능enum class Enumeration : unsigned int {
Val1,
Val2,
Val3 = 100,
Val4 // = 101
};
RIGHT ANGLE BRAKET
옛날에는 컴파일러가 템플릿 키워드 중첩해서 쓴 것과 << 연산자랑 헷갈렸음이젠 컴파일러가 알아서 잘 해석해줌
언어 기능 강화안 되던 게 됩니다
VARIADIC TEMPLATES
템플릿 패러미터를 가변적으로 받을 수 있게 변경됨이거 덕분에 템플릿 메타 프로그래밍 할 때 패러미터 개수 문제로 골머리 썩던 게 해결자세한 내용은 http://en.wikipedia.org/wiki/Variadic_templates 참고
NEW STRING LITERALS
문자 인코딩 타입을 정할 수 있게 되었다u8"I'm a UTF-8 string."
u"This is a UTF-16 string."
U"This is a UTF-32 string.“
R”*(This is a “raw” string)*”
이 때문에 새로운 캐릭터 타입이 추가됨char16_t
char32_t
MULTITHREADING MEMORY MODEL
C++11 에 멀티스레드 라이브러리가 추가 됨관련해서 메모리 모델 추가 됨
Memory ordering
Memory barrier
Consistency model
Shared memory
LONG LONG INT
드디어 64 비트 정수가 표준화 됨그 전에는 컴파일러들이 그냥 지원하는 거였음
STATIC ASSERTIONS
컴파일 타임에 걸 수 있는 assertion 이 생김주로 전처리 지시자나 템플릿 사용등을 검사
static_assert((GREEKPI > 3.14) && (GREEKPI < 3.15), "GREEKPI is inaccurate!");
표준 라이브러리 변경언어가 바뀌었으니 표준 라이브러리도 바뀌었겠죠 ?
기존 라이브러리에 C++11 적용적용 된 기능들
Rvalue reference 와 move constructor
UTF-16, UTF-32
Variadic templates
auto, decltype
explicit conversion operators
default/deleted functions
THREADING FACILITIES
앞서 얘기한대로 스레딩 관련 컴포넌트들 추가std::thread, std::mutex, std::recursive_mutex
std::future, std::promise, std::async
etc.
thread_pool 은 아직 안 들어감
NEW CONTAINERS
Tuple
std::tuple
Hash tables
std::unordered_set
std::unordered_map
std::unordered_multiset
std::unordered_multimap
REGULAR EXPRESSION
드디어 C++ 에 정규표현식이 들어갔습니다 !
std::regex, std::regex_search, std::match_results etc.
SMART POINTERS
스마트 포인터가 추가됨std::unique_ptr // ownership 을 1 개로 제한std::shared_ptr // 공유 포인터std::weak_ptr // 공유 포인터의 상호참조를 방지하고 싶을 때std::auto_ptr // 메모리 자동 해지 포인터 . ownership 문제가 있음
그 외에 다루지 않은 부분은C++11 표준 문서나 위키피디아를 참고하시면 됩니다
참고Wikipedia : http://en.wikipedia.org/wiki/C%2B%2B11
rein.kr : http://rein.kr/blog/archives/2371