Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

프로그래밍 대회: C++11 이야기

44,987 views

Published on

ACM-ICPC, Topcoder 등 프로그래밍 대회를 위한 간단한 C++11 소개

Published in: Technology
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ,Download or read Ebooks here ... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • If you want to download or read this book, copy link or url below in the New tab ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ,Download or read Ebooks here ... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • If you want to download or read this book, copy link or url below in the New tab ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THI5 BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

프로그래밍 대회: C++11 이야기

  1. 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 프로그래밍 대회: C++11 이야기 (DRAFT) 약간의 코딩 스타일 얘기도 덤으로 Jongwook Choi (@wookayin) 2015년 1월 24일
  2. 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction // elcome to C++11 using matrix = vector<vector<long>>; auto fn = [=](const int x, const int y) { return x > y };
  3. 3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C++11 C++ 프로그래밍 언어의 최신 표준 스펙 (C++14는 아직..) 그동안 써왔던 예전 버전 : C++98, C++03
  4. 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C++11 : Current Status 2011년 8월, C++11 언어 스펙 확정 컴파일러 현황 GNU C++ : Complete (G++ 4.8, 4.9 for regex) Clang C++ : Complete (Clang 3.3) MSVC++ : Almost Complete (VS 2012), and much more (VS 2013) C++11 를 활성화하려면, --std=c++11 (or --std=c++0x) 옵션을 command line 에 추가해야 함
  5. 5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C++11 : Current Status Compatibility Chart g++ : http://gcc.gnu.org/projects/cxx0x.html MSVC : http://msdn.microsoft.com/en-us/library/hh567368.aspx PS에서 사용되는 코드 수준에서 필요한 대부분의 C++11 기능들은 현재 사용가능한 (혹은 디폴트) 컴파일러 버전에서 대부분 지원함.
  6. 6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 다룰 내용들 C++11 의 신기능은 매우(..) 많지만, 어렵고 복잡한 거 다 빼고 프로그래밍 대회와 관련있는 실용적인(?) 것만 간단하게 훑어봅시다. auto range-based for initializer lists std::tuple STL 컨테이너 개선 lambda function move, r-value reference 기타 잡다한 내용
  7. 7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . auto map<pair<string, string>, vector<int> > M; for(map<pair<string, string>, vector<int> >::iterator it = M.begin(); it != M.end(); ++ it) { // TF... }
  8. 8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . auto auto : 컴파일 타임에 변수의 type을 자동으로 추론하여 선언하기 map<pair<string, string>, vector<int> > M; for(auto it = M.begin(); it != M.end(); ++ it) { // Olleh! } // map<pair<string, string>, vector<int>>::iterator it;
  9. 9. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Range-based for (STL 컨테이너 순회를 위한) 옛날 방식: set<string> names; for(set<string>::iterator it = names.begin(); it != names.end(); ++ it) const string &s = *it; } vector<vector<int> > G; for(unsigned i = 0; i < G[u].size(); ++i) { int v = G[u][i]; // ... }
  10. 10. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Range-based for C++11의 새로운 방식: set<string> names; for(const string &s : names) { // ... } vector<vector<int> > G; for(int v : G[u]) { // ... }
  11. 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Range-based for std::map 은 pair 로 받아옵니다. map<string, int> M; for(auto &it : M) { const string &key = it.first; // const ! int value = it.second; // ... }
  12. 12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Range-based for : 주의 (1) range-based for문에서 선언하는 변수가 레퍼런스(reference) 타입이 아니면, 값 복사가 발생하므로 주의합니다. auto 도 마찬가지입니다. vector<LargeStruct> data; // rong! (copy by value) for(LargeStruct a : data) { ... } for(auto a : data) { ... } // Preferred way (avoid copying) for(auto& a : data) { ... } for(const auto& a : data) { ... }
  13. 13. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Range-based for : 주의 (2) // iterate 4 times (includes null character!!) for(char c : ”RGB”) { ... } // iterate 3 times for(char c : string(”RGB”)) { ... }
  14. 14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Range-based for : FAQ 왜 이런걸 써야 하나? 편하다! vector를 순회할 때, 값/레퍼런스 말고 index도 필요하면? 딱히 방법이 없다. 이럴 땐 옛날 방식을 사용하자
  15. 15. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializer lists STL 컨테이너를 더 간단하게 초기화할 수 있다. (기존에는 딱히 좋은 방법이 없었음) vector<int> a = {1, 2, 3, 4}; map<string, int> b = { {”a”, 1}, {”b”, 2} }; pair<int, long long> c = {3, 4LL}; pair<vector<int>, pair<char, char>> d = { {1, 2, 3}, {’A’, ’B’} } tuple<int, string, int> e = {2222, ”Yellow”, 22};
  16. 16. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializer lists 아마 이런 것이 유용할 것으로 생각됩니다 (..) pair<int, string> getName() { if(...) { return make_pair(0, ”ACM-ICPC”); } else { return {1, ”C++”}; // easy, huh? } }
  17. 17. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializer lists 사용자 정의 구조체/클래스도 됨! struct vector3 { int x, y, z; vector3(int x=0, int y=0, int z=0) : x(x), y(y), z(z) { } }; vector3 O = vector3(0, 0, 0); // 생성자 사용 vector3 V = {1, 2, 3}; // initializer list 사용 // 생성자 없이 explicit type을 주어 값 생성 vector3_add( vector3{0, 0, 0}, vector3{0, 0, 0} ); // 함수 파라메터에 따라 자동으로 type 추론이 가능 vector3_add( {0, 0, 0}, {0, 0, 0} );
  18. 18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializer lists : 응용 // the old-way int minValue = min(x, min(y, z)); // C++11 에서는, std::min, std::max 등의 함수가 // std::initializer_list<T> 타입을 받을 수 있도록 overload 되어 있음 int minValue = min({x, y, z}); int maxValue = max({x, y, z}); tie(minValue, maxValue) = minmax({p, q, r, s});
  19. 19. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initializer lists : 응용 (2) for문으로 돌리기도 뭐하고, copy&paste 신공으로 여러줄 쓰기도 뭐한데 특정 부분 또는 argument만 달라지는 경우에, range-based for 문과 함께 유용함. for(const auto x : {2, 3, 5, 7}) { foo(x); }
  20. 20. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . In-class member initializers struct 또는 class의 field를 초기화할 수 있다. (생성자에 귀찮게 매번 안 써도 됨) class AwesomeLibrary { int sum = 0; // C++03 : Error, C++11 : O int n; }; G++ 에서는 4.7 이상부터 지원, MSVC 2012에서는 안됨
  21. 21. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tuple 기존에는 두개짜리 std::pair<T1, T2> 만 있었다. 값 3개를 묶어서 들고 다니려면 어떻게 해야할까요? // 1. nested pair // a.first, a.second.first, a.second.second (orz) pair<int, pair<int, int> > a; // 2. 구조체 직접 작성 struct xyz { int x, y, z; };
  22. 22. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tuple // tuple<T1, T2, T3, T4, ...> tuple<int, string, int> t(1, ”hello”, -1); // make_pair 처럼 make_tuple 을 사용 t = make_tuple(1, ”hello”, -1); // std::get - tuple 에서 값 추출하기 int v1 = get<0>(t); // 1 string v2 = get<1>(t); // hello int z = get<2>(t); // -1
  23. 23. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tuple, tie std::tie를 쓰면 tuple 의 값을 여러 변수에 동시에 받아올 수 있어요. int a = 3, b = 4; tie(b, a) = make_tuple(a, b); // b=3, a=4 int x, y; tie(x, y, ignore) = make_tuple(3, 4, 5); // x=3, y=4
  24. 24. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tuple 예제: lexicographical comparison 쉽게 하기 sort(a.begin(), a.end(), [&](const Elem &x, const Elem &y) { return make_tuple(x.score, -x.age, x.submission) < make_tuple(y.score, -y.age, y.submission); }); /* x.score != y.score ? (x.score < y.score : (x.age != y.age ? x.age > y.a if(x.score != y.score) return x.score < y.score; */
  25. 25. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tuple 예제: lexicographical comparison 쉽게 하기 Smaller number of vowels (aeiou) On tie, larger length On tie, lexicographically smallest string findBest(string a, string b, string c) { auto q = min({ make_tuple( vowels(a), -(int)a.size(), a ), make_tuple( vowels(b), -(int)b.size(), b ), make_tuple( vowels(c), -(int)c.size(), c ) }); return get<2>(q); } (참고) make_tuple을 쓰면 copy가 일어나고, std::tie를 쓰면 일어나지 않는다.
  26. 26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . STL 컨테이너 vector, list, queue, deque 등에 메소드 emplace(...) 혹은 emplace_back(...) 등이 추가되었다. vector< pair<int, int> > A; A.push_back( make_pair(3, 4) ); // {3, 4}를 추가 A.emplace_back( 3, 4 ); // 위와 같은 일을 함. queue< tuple<int, int, int> > Q; // Q.push( {1, 2, 3 }); Q.emplace( 1, 2, 3 ); 대강 말하면, 모든 argument가 컨테이너 내 element의 type의 생성자에 그대로 전달된다고 생각하면 쉽다.
  27. 27. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 새로운 STL 컨테이너 : unordered_set, unordered_map std::set, std::map : ‘sorted-key’ set/dictionary 내부 구현은 R/B Tree 를 사용함 – O(log n) std::unordered_set, std::unordered_map : hash 를 이용한 구현 (이론적으로) O(1) 시간복잡도 std::set, std::map 와 (거의) 같은 인터페이스 자매품으로 std::unordered_multiset, std::unordered_multimap 도 있다. unordered_map<long long, int> pows; for(int i=0; i<63; ++i) pows[1LL<<i] = i;
  28. 28. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hash set/map : 성능 대회에서 사용되는 수준의 data 크기로는, ordered set/map에 비해 약간의 성능 향상은 있다 (그러나 significant 하지는 않음) 32bit 정수형 타입, n = 1, 000, 000 : 2x ~ 3x faster 덩치큰 구조체 등 : hash 계산에 따라 비슷하거나 더 느릴수도 있다. 인터페이스 차이가 별로 없으므로, ordering이 중요하지 않다면 hash를 써도 손해볼 것은 없다.
  29. 29. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 사용자 정의 struct에 hash를 추가하는 법 struct MyType { string name; int age; // implement operator == }; /* std::hash<T> 에 operator() 를 구현합니다. */ namespace std { template <> struct hash<MyType> { size_t operator (const MyType &o) const { size_t h; h = (hash<string>())(name); h ^= (hash<int>())(age) >> 1; return h; } }; }
  30. 30. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Function Lambda : 익명 함수 // [ captures ]( parameters ){ body } auto func = [](){}; func(); // call just like a classical function! (익명) 함수를 값이나 객체처럼 취급이 가능하다 (e.g. 다른 함수의 argument로 넘길 수 있다!). 언어 차원에서 Closure 를 지원하고 있다. 그게뭐죠 먹는건가요
  31. 31. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Goodnesses : STL (거의) 모든 STL 알고리즘은 lambda 함수를 지원합니다. vector<int> v = ...; for_each(v.begin(), v.end(), [](int x) { cout << x << ’ ’; }); // 특히 정렬에서 lambda 함수가 가장 유용하다. // comparator를 번거롭게 만들거나, 먼 곳에 두지 않아도 됨! sort(a.begin(), a.end(), [&](int x, int y) { return priority[x] > priority[y]; }); auto by_abs = [](int x, int y) { return abs(x) < abs(y); }); sort(a.begin(), a.end(), by_abs);
  32. 32. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Goodnesses : Local functions C++03 에서는, local type 선언은 가능하지만 template argument 로 사용이 불가능하다. 따라서 sort의 comparator 로 사용할 수 없어 함수 바깥으로 빼야하는 불편함이 있었다. void localFunction( vector<int> &data ) { struct AbsComparator { bool operator() (const int a, const int b) { return abs(a) < abs(b); }; }; sort(data.begin(), data.end(), AbsComparator()); // ERROR in C++03, O in C++11 }
  33. 33. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Goodnesses : Local functions 마찬가지로 lambda를 사용하면, 해당 함수가 사용되는 곳에서 코드를 작성할 수 있으므로 전역 변수의 사용을 피하고 code의 locality를 키울 수 있으므로 좋다. // Using Lambda : ind of local functions (even can capture local variables) void localFunction( const vector<point> &P ) { const point O = P[0]; // reference 사용하지 않도록 주의 (why?) auto by_distance = [&](const point &A, const point &B) { double OA = (A - base).norm(); double OB = (B - base).norm(); return OA < OB; }; sort(P.begin(), P.end(), by_distance); // O } Closure 덕택에 contextual variable 를 사용할 수 있다.
  34. 34. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Goodnesses : 예제 (1) int solve(vector<int> &a, vector<int> &b) { int n = (int) a.size(); int S = 0, T = V - 1; int V = 2 * n + 2; auto L = [&](int x) { return x + 1; }; auto R = [&](int x) { return x + 1 + n; }; NetworkFlow f(V); for(int i=0; i<n; ++i) { f.addEdge(S, L(i), a[i]); f.addEdge(L(i), R(i), a[i]); f.addEdge(R(i), T, b[i]); } /* ... */ }
  35. 35. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Goodnesses : 예제 (2) double ternary(function<double (double)> f, double l, double r) { for(int iter = 0; iter < 100; ++ iter) { double p = (l * 2 + q) / 3, q = (l + 2 * q) / 3; if (f(p) > f(q)) r = q; else l = p; } return (l + r) / 2.0; } double solve() { auto f = [&](double x) -> double { return x * x; }; double x0 = ternary(f, 0.0, 1.0); return f(x0); }
  36. 36. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda Goodnesses : 예제 (3) /* akarta 2013 */ RangeTree t0([](long long x) -> long long { return x; } ); RangeTree t1([](long long x) -> long long { return (x * (x + 1) / 2) % MOD; } ); RangeTree t2([](long long x) -> long long { return (x * (x + 1) * (2 * x + 1) / 6 ) % MOD; } ); RangeTree t3([](long long x) -> long long { return (((x * (x + 1) / 2) % MOD) * ((x * (x + 1) / 2) % MOD)) % MOD; } );
  37. 37. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda : Recursive Recursive 익명함수도 가능하다. 다만, C++14 전까지는 형태가 약간 이상함(..) std::function<int(int)> f; // include <functional> f = [&f](int x) -> int { if(x <= 1) return x; return f(x - 1) + f(x - 2); };
  38. 38. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda : Recursive (예제) 어떤 함수 안에서만 필요한 DFS 짜야하는데.. 전역변수로 빼긴 좀 싫고.. bool isGraphConnected(vector<vector<int>> &G) { vector<bool> visited(G.size(), false); std::function<void (int)> dfs = [&](int u) { if (visited[u]) return; for (int v : G[u]) dfs(v); }; dfs(0); for(size_t i = 0; i < G.size(); ++ i) if (!visited[i]) return false; return true; }
  39. 39. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lambda + STL Algorithms vector<int> primes = { 2, 3, 5, 7, 11 }; auto is_even = [](int n) { return (n & 1) == 0; } bool allEven = all_of(primes.begin(), primes.end(), is_even); /* allEven = false; for(int x : primes) if(! is_even(x)) { allEven = false; break; } */
  40. 40. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Move Semantics Matrix 곱셈 함수를 만든다고 가정해봅시다. typedef vector<vector<int>> Matrix; // output 대상을 argument로 넣는 것은 // 일반적으로 좋은 코딩 습관이 아닙니다. void multiply(const Matrix &A, const Matrix &B, Matrix &C); // C를 바깥에서 생성해야 하므로 사용하기도 난감합니다. Matrix C; multiply(A, B, C); print(C);
  41. 41. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Move Semantics C++ 스타일로 하면: // 값(Matrix)으로 리턴합니다. Matrix operator * (const Matrix &A, const Matrix &B) { size_t n = A.size(); Matrix C(n, n); REP(i, n) REP(j, n) REP(k, n) C[i][j] += A[i][k] * B[k][j]; return C; // return by value } // syntax도 깔끔하고, 직관적인 operator 스타일로 쓸 수도 있음.. Matrix E = (D * D) + I; E = E * E;
  42. 42. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Move Semantics 값 복사가 일어나지는 않나? Matrix면 100 × 100의 메모리 복사가 일어나서 느리지는 않는가? 옛날 C++에서는, 값 복사가 일어날 수도 있다. RVO (Return Value Optimization) 최적화가 지원되는 컴파일러에서는 복사가 일어나지 않을 수도 있다. C++11 에서는 move semantics 에 의해 (항상) 값 복사가 일어나지 않는다.
  43. 43. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . R-Value Reference L-Value, R-Value 에 대해 자세히 설명하려면 어려우니까 (컴파일러 들으세요..), 간단히 말해서 L-Value는 주소값이 있는 변수, R-Value는 주소값이 없는 ‘임시 객체’ 라고 생각하면 됩니다. vector<int> concat(const vector<int> &a, const vector<int> &b); vector<int> range(int n); vector<int>& foo(int); vector<int> x; // L-value cout << range(10) // --------- : R-value cout << foo(0); // ------ : L-value
  44. 44. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example 아래와 같은 경우가 종종 있다(?) 어떻게 고쳐야 할까? vector<int> concat (vector<int> &a, vector<int> &b) { // (!) // ... } vector<int> range (int n) { /* ... */ } int main() { vector<int> c; c = concat ( vector<int> { -1 }, range(5) ); // (?) for(int x : c) cout << x << ’ ’; cout << endl; return 0; }
  45. 45. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example 해결책 1: Reference가 아닌 값으로 함수를 선언한다. (문제점) 값 복사가 일어난다. vector<int> concat (vector<int> a, vector<int> b) { // (!!!!!!!!) // ... } vector<int> range (int n) { /* ... */ } int main() { vector<int> c; c = concat ( vector<int> { -1 }, range(5) ); // (?) for(int x : c) cout << x << ’ ’; cout << endl; return 0; }
  46. 46. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example 해결책 2: Reference를 유지하고, 불편하게 사용한다. (문제점) 코드의 가독성이 떨어지고 불필요한 변수 선언을 해야 한다. vector<int> concat (vector<int> &a, vector<int> &b) { // (!) // ... } vector<int> range (int n) { /* ... */ } int main() { vector<int> a = vector<int> { -1 }, b = range(5); vector<int> c = concat( a, b ); // (!!!!!!!!) for(int x : c) cout << x << ’ ’; cout << endl; return 0; }
  47. 47. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example 해결책 3: R-Value Reference를 사용한다. (문제점) L-Value 인자는 R-Value로 implicit 변환이 안된다. vector<int> concat (vector<int> &&a, vector<int> &&b) { // (!!!!!!!!) // ... } vector<int> range (int n) { /* ... */ } int main() { vector<int> c; c = concat ( vector<int> { -1 }, range(5) ); // (?) for(int x : c) cout << x << ’ ’; cout << endl; return 0; }
  48. 48. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Move Constructor Move Constructor 가 있는 클래스(STL 컨테이너)에 대해서는, 임시 객체(R-value)를 받아 객체를 생성할 수 있다. 이 때, 값 복사 없이 메모리 이동하는 꼴이 되는데, 이것을 move semantic 이라 한다. template<typename T> struct vector { vector(); vector(size_t size); // ... constructors vector(vector<T> &a); // copy constructor (복사) vector(vector<T> &&a); // move constructor (!!!) }
  49. 49. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example 완벽한 해법은 아니지만 일단 아래와 같이 하면 […] vector<int> concat (vector<int> &&a, vector<int> &&b) { // ... } vector<int> concat (const vector<int> &a, const vector<int> &b) { // ... } vector<int> range (int n) { /* ... */ } { // ... c = concat ( vector<int> { -1 }, range(5) ); // L-Value c = concat ( c, c ); // R-Value }
  50. 50. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 약간 오버해보자 std::move Perfect Forwarding
  51. 51. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Another Example 이런 코드를, 성능 걱정 없이 그냥 만들어 쓰면 됩니다. vector<int> generate_array(int n) { vector<int> a; a.push_back(A); for(int i=1; i<n; ++i) a.push_back((a.back() * B + C) % D); return a; } for (auto x : generate_array(1000000)) // no copy !!! cout << x << ’n’;
  52. 52. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 결론: R-Value, Move Semantics 그냥 C++11 컴파일 옵션을 넣기만 해도, (코드는 바뀐거 없어도) vector, string 등의 연산자들이 (약간) 빨라진다. string h = ”hello”, a = ”world”; h = h + ” ” + a + ” ? ” + h + ” ICPC” + a; 사용자 정의 타입에 move semantics 를 지원하면 값 복사를 피할 수 있어 빨라질 수 있다. 근데 짜기가 어렵지
  53. 53. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . std::array array<int, 6> a = { 1, 2, 3 }; // int a[6]; vector 와 달리, 크기가 고정된 정적(static) 배열이다. int[] 와의 차이점은? STL algorithm 함수들에 적용이 가능함 (e.g. begin, end) 값 복사, 사전순 비교 등이 쉽게 가능 (as operator, no memcpy!) assertive 하게 동작 (out-of-index 일 때 바로 throw) 대회에서는 사용성이 별로 없다.
  54. 54. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Standardized Timer Library See std::chrono. 윈도우/리눅스 등 여러 플랫폼에서 공통으로 사용가능하다. using namespace std::chrono; // include <chrono> auto _start = system_clock::now(); // or high_resolution_clock::now() /* SOME EAVY OBS here */ auto _end = system_clock::now(); // or high_resolution_clock::now() long millisecs = duration_cast<milliseconds>(_end - _start).count(); Linux only 라면.. gettimeofday() 써도 된다 (API 구린건 마찬가지)
  55. 55. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Regex 정규식 기능이 C++11 부터 추가되었다. (주의) G++는 4.9.0 이상부터만 동작한다. if( regex_match(”ABCD”, regex(”(A|B)C(.*)D”)) ) { // ... }
  56. 56. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Random Library 더 좋은 랜덤 성능! (rand() 는 uniformity가 떨어지고, RAND_MAX가 32767인 머신도 있다) std::mt19937 eng; // Mersenne Twister std:::uniform_int_distribution<int> U(-100, 100); for (int i = 0; i < n; ++i) cout << U(eng) << std; 마라톤 매치 같은거 할 거 아니면 쓸모 없다
  57. 57. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Thread 멀티쓰레딩을 쉽게 할 수 있다. ICPC에서는 안되지만, GCJ나 HKcup 에서는 쓰면 유용할거에요
  58. 58. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 그 외 사소한 개선 연속된 > 사이에 공백이 없어도 됨 vector<vector<int> > a; // C++03... vector<vector<int>> a; // C++03 : Error, C++11 : O
  59. 59. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 그 외 사소한 개선 std::to_string string s = std::to_string(10); string s = std::to_string(3.1415926535); std::stoi, std::stol, std::stoll int x = stoi(”-1”); long long y = stoll(”2147483648”); long long z = stoll(”1000...0000”, 0, 2); // 4294967296
  60. 60. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . nullptr 예전의 NULL은 (void*)0 이고, null pointer 는 nullptr 를 사용하면 됩니다.
  61. 61. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128-bit integer C++11 표준은 아니지만 GCC에는 __int128_t (또는 __int128), __uint128_t (또는 __uint128) 타입이 생겼다. 일부 환경에서만 됨 (e.g. 64-bit Linux on Intel) 10진수로 출력하는 내장 함수가 없다 (…)
  62. 62. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Further References cppreference.com : http://en.cppreference.com/w/ C++11 FAQ : http://www.stroustrup.com/C++11FAQ.html

×