Top Banner
Nexon Talk 2017 “C++17 Key Features Summary“ (Ver 2) 옥찬호 Nexon Korea, Microsoft MVP [email protected]
83

C++17 Key Features Summary - Ver 2

Jan 22, 2018

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: C++17 Key Features Summary - Ver 2

Nexon Talk 2017

“C++17 Key Features Summary“(Ver 2)

옥찬호Nexon Korea, Microsoft MVP

[email protected]

Page 2: C++17 Key Features Summary - Ver 2

소개• 옥찬호 (Chris Ohk)

• Nexon Korea Game Programmer

• Microsoft Visual C++ MVP

• 페이스북 그룹 C++ Korea 대표

• IT 전문서 집필 및 번역다수

• 게임샐러드로 코드 한 줄 없이 게임만들기 (2013)

• 유니티 Shader와 Effect 제작 (2014)

• 2D 게임 프로그래밍 (2014)

• 러스트 핵심 노트 (2017)

• 모던 C++ 관련 도서 집필 및 번역중… (2017? 2018?)

Page 3: C++17 Key Features Summary - Ver 2

시작하기 전에… Nexon Talk 2017C++17

• C++17에추가될 주요기능들을 설명합니다.

• C++17에추가될 주요기능 뿐만아니라,

이후 TS(Technical Specification)에 추가될기능들도소개합니다.

• C++17에추가될기능 중 C++11/14 지식이 필요한경우,

이해를 돕기 위해 사전 지식을 먼저 설명합니다.

• 모든 예제코드는발표 이후 Github를 통해 제공됩니다.

• Ver 1에서 언급되지않은 추가기능들을소개합니다.

Page 4: C++17 Key Features Summary - Ver 2

C++17 기능 선호도 조사 Nexon Talk 2017C++17

Page 5: C++17 Key Features Summary - Ver 2

C++17 기능 선호도 조사 Nexon Talk 2017C++17

Page 6: C++17 Key Features Summary - Ver 2

현재 표준 C++ 진행 상황 Nexon Talk 2017C++17

Page 7: C++17 Key Features Summary - Ver 2

현재 표준 C++ 진행 상황 Nexon Talk 2017C++17

Page 8: C++17 Key Features Summary - Ver 2

C++17 주요 기능 Nexon Talk 2017C++17

• Folding expressions

• New rules for auto deduction from braced-init-list

• constexpr lambdas

• Lambda capture this by value

• Attributes: [[fallthrough]], [[nodiscard]], [[maybe_unused]]

• inline variables

• namespace A::B

Page 9: C++17 Key Features Summary - Ver 2

C++17 주요 기능 Nexon Talk 2017C++17

• Structured bindings

• constexpr if

• if (init; condition), switch (init; condition)

• std::any, std::optional, std::variant, std::string_view

• std::invoke, std::apply

• try_emplace and insert_or_assign for std::map

• File System TS v1, Parallelism TS v1

Page 10: C++17 Key Features Summary - Ver 2

Folding expression Nexon Talk 2017C++17

• C++11의가변템플릿 (Variadic Template)template <typename T>void PrintList(T value)

std::cout << value << std::endl;

template<typename First, typename ...Rest>void PrintList(First first, Rest ...rest)

std::cout << first << ", ";PrintList(rest...);

Page 11: C++17 Key Features Summary - Ver 2

Folding expression Nexon Talk 2017C++17

• C++11의가변템플릿 (Variadic Template)PrintList(42, "Hello", 2.3, 'a'); 42, Hello, 2.3, a

PrintList(first = 42, ...rest = “hello“, 2.3, 'a');42PrintList(first = 42, ...rest = 2.3, 'a');

helloPrintList(first = 42, ...rest = 'a');

2.3PrintList(first = 'a');

재귀 함수를 끝내기 위한

별도의 함수 필요!

template <typename T>void PrintList(T value)

std::cout << value << std::endl;

Page 12: C++17 Key Features Summary - Ver 2

Folding expression Nexon Talk 2017C++17

• 가변템플릿을사용해 표현식을간단하게구현할 수 있는기능

Fold = 접는다, Expression = 표현식→ “표현식을 접는다!”

template<typename... Args>bool All(Args... args)

return (... && args);

int main()

// ((true && true) && true) && falsebool b = All(true, true, true, false);

(…) && false

((…) && true) && false

(((…) && true) && true) && false

((true && true) && true) && false

Page 13: C++17 Key Features Summary - Ver 2

Folding expression Nexon Talk 2017C++17

• Folding expression 문법

1. Unary right fold (E op …)

→ E1 op (… op (En-1 op En))

2. Unary left fold (… op E)

→ ((E1 op E2) op …) op En

3. Binary right fold (E op … op l)

→ E1 op (… op (En-1 op (En on l)))

4. Binary left fold (l op … op E)

→ (((l op E1) op E2) op …) op En

Page 14: C++17 Key Features Summary - Ver 2

Folding expression Nexon Talk 2017C++17

• Example 1 : Binary right fold (E op … op l)

template<typename ...Args>int Sum(Args&&... args)

return (args + ... + (1 * 2));

int main()

Sum(1, 2, 3, 4);

Page 15: C++17 Key Features Summary - Ver 2

Folding expression Nexon Talk 2017C++17

• Example 2 : Binary left fold (l op … op E)

template<typename ...Args>void Printer(Args&&... args)

(std::cout << ... << args) << '\n';

int main()

Printer(1, 2, 3, "abc");

Page 16: C++17 Key Features Summary - Ver 2

New rules: auto deduction Nexon Talk 2017C++17

• C++11의문제 : auto와 로인해발생하는모호함

int main()

int v1 123 ; // 1auto v2 123 ; // 2auto v3 = 123 ; // 3auto v4 1, 2, 3 ; // 4auto v5 = 1, 2, 3 ; // 5

intstd::initializer_list<int>std::initializer_list<int>std::initializer_list<int>std::initializer_list<int>

int main()

int v1 123 ; // intauto v2 123 ; // std::initializer_list<int>auto v5 = 1, 2, 3 ; // std::initializer_list<int>

Page 17: C++17 Key Features Summary - Ver 2

New rules: auto deduction Nexon Talk 2017C++17

• C++17에서는 auto와 를 통한 초기화리스트의모호함을제거함

int main()

auto x1 1 ; // intauto x2 = 2 ; // initializer_list<int>auto x3 = 1,2 ; // initializer_list<int>auto x4 1,2 ; // error

Page 18: C++17 Key Features Summary - Ver 2

constexpr lambdas Nexon Talk 2017C++17

• C++11의상수 표현식 (constexpr, Constant Expression)

• 쉽게 구현할 수 있는 메타 프로그래밍

• 변수의값이나함수의내용을 컴파일 타임에 처리

• 함수내에서는 하나의 표현식만 사용할수 있고

반드시 리터럴 타입을 반환해야했지만, C++14에서 제한이 다소 완화됨

constexpr int n = 0; // OKconstexpr int m = time(NULL); // error C2127

constexpr int square(int x)

return x * x;

int n;std::cin >> n;square(n); // Processed in run-timesquare(10); // Processed in compile-time

Page 19: C++17 Key Features Summary - Ver 2

constexpr lambdas Nexon Talk 2017C++17

• C++11의람다식 (Lambda Expression)

[my_mod] (int v) -> int return v % my_mod; 개시자

(Introducer Capture)

인자(Arguments)

반환 타입(Return Type)

함수의 몸통(Statement)

Page 20: C++17 Key Features Summary - Ver 2

constexpr lambdas Nexon Talk 2017C++17

• C++11의람다식 (Lambda Expression)

int x = 10, y = 20;[] ; // Do not capture[x](int arg) return x; ; // value(Copy) capture x[=] return x; ; // value(Copy) capture all[&] return y; ; // reference capture all[&, x] return y; ; // reference capture all except x[=, &y] return x; ; // value(Copy) capture all except y[this] return this->something; ; // this capture[=, x] ; // error[&, &x] ; // error[=, this] ; // error[x, x] ; // error

Page 21: C++17 Key Features Summary - Ver 2

constexpr lambdas Nexon Talk 2017C++17

• “람다식에 constexpr을 허하노라!”int main()

constexpr auto add = [](int a, int b) return a + b; ;Test<add(1, 2)> t1;

auto add2 = [](int a, int b) constexpr return a + b; ;Test<add2(1, 2)> t2;

auto add3 = [](int a, int b) return a + b; ;constexpr int c = add3(1, 2);constexpr int(*f)(int, int) = add3;Test<add3(1, 2)> t3;

Page 22: C++17 Key Features Summary - Ver 2

constexpr lambdas Nexon Talk 2017C++17

• Example : 팩토리얼int main()

constexpr auto Factorial = getFactorializer();static_assert(Factorial(5) == 120, "");static_assert(Factorial(10) == 3628800, "");

Page 23: C++17 Key Features Summary - Ver 2

constexpr lambdas Nexon Talk 2017C++17

constexpr auto getFactorializer = [] unsigned int optimization[6] = ;auto for_each = [](auto* b, auto* e, auto pred)

auto* it = b;while (it != e) pred(it++ - b);

;for_each(optimization, optimization + 6, [&](int n)

if (!n) optimization[n] = 1;else optimization[n] = n * optimization[n - 1];

);auto FacImpl = [=](auto fac, unsigned n)

if (n <= 5) return optimization[n];return n * fac(fac, n - 1);

;auto Fact = [=](int n)

return FacImpl(FacImpl, n);;return Fact;

;

Page 24: C++17 Key Features Summary - Ver 2

this capture by value Nexon Talk 2017C++17

• C++11에서는레퍼런스에의한 this 캡처만 지원했었음

• C++17부터는값에의한 this 캡처를 지원함

struct MyObj

int value 123 ;

auto getValueCopy()

return [*this] return value; ;auto getValueRef()

return [this] return value; ;

;

MyObj mo;auto valueCopy = mo.getValueCopy();auto valueRef = mo.getValueRef();

mo.value = 321;valueCopy(); // 123valueRef(); // 321

Page 25: C++17 Key Features Summary - Ver 2

Attributes Nexon Talk 2017C++17

• 타입, 개체, 코드 등에 구현 정의 특성을 부여

• C++14에추가된특성• [[noreturn]] : 이 함수는 리턴하지않음

• [[carries_dependency]] : 종속성 체인이함수안팎으로 전파됨

• [[deprecated]] : 사용할 수 있지만, 권장하지않음 (더이상 사용 X)

• C++17에추가된특성• [[fallthrough]] : switch-case 문에서사용, 완료되지않음을나타냄

• [[nodiscard]] : 함수의 리턴값이 있는데 버리는 경우 경고문을표시

• [[maybe_unused]] : 사용하지않는변수에 대해 경고문을표시하지않음

Page 26: C++17 Key Features Summary - Ver 2

Attributes Nexon Talk 2017C++17

• Example 1 : [[noreturn]] - 이함수는 리턴하지않음

• [[noreturn]] void f()

throw "error"; // OK

[[noreturn]] void q(int i)

// behavior is undefined// if called with an argument <= 0if (i > 0) throw "positive";

Page 27: C++17 Key Features Summary - Ver 2

void f(int n)

void g(), h(), i();switch (n)case 1:case 2:

g();[[fallthrough]];

case 3: // no warning on fallthroughh();

case 4: // compiler may warn on fallthroughi();[[fallthrough]]; // illformed, not before a case label

Attributes Nexon Talk 2017C++17

• Example 2 : [[fallthrough]] - switch-case 문에서 사용, 완료되지않음을 나타냄

Page 28: C++17 Key Features Summary - Ver 2

struct [[nodiscard]] error_info ;error_info enable_missile_safety_mode();void launch_missiles();void test_missiles()

enable_missile_safety_mode(); // compiler may warn// on discarding a nodiscard value

launch_missiles();error_info& foo();void f1()

foo(); // nodiscard type is not returned by value, no warning

Attributes Nexon Talk 2017C++17

• Example 3 : [[nodiscard]] - 함수의 리턴값이 있는데버리는 경우 경고문을 표시

Page 29: C++17 Key Features Summary - Ver 2

Attributes Nexon Talk 2017C++17

• Example 4 : [[maybe_unused]] - 사용하지않는 변수에 대해 경고문을 표시하지않음

[[maybe_unused]] void f([[maybe_unused]] bool thing1,[[maybe_unused]] bool thing2)

[[maybe_unused]] bool b = thing1 && thing2;assert(b); // in release mode, assert is compiled out, and b is unused

// no warning because it is declared [[maybe_unused]] // parameters thing1 and thing2 are not used, no warning

Page 30: C++17 Key Features Summary - Ver 2

inline variables Nexon Talk 2017C++17

• 클래스템플릿에서 static 변수를 지원하는편리한방법// until C++14template <class Dummy>struct Kath_

static std::string const hi;;

template <class Dummy>std::string const Kath_<Dummy>::hi = “Zzzzz...";

using Kath = Kath_<void>; // Allows you to write `Kath::hi`.

Page 31: C++17 Key Features Summary - Ver 2

inline variables Nexon Talk 2017C++17

• 클래스템플릿에서 static 변수를 지원하는편리한방법// since C++17struct Kath

static std::string const hi;;

template <class Dummy>inline std::string const Kath::hi = “Zzzzz..."; // Simpler!

Page 32: C++17 Key Features Summary - Ver 2

inline variables Nexon Talk 2017C++17

• 클래스템플릿에서 static 변수를 지원하는편리한방법// since C++17struct Kath

static inline std::string const hi = “Zzzzz..."; // Simplest!;

“An inline static data member can be defined in the class definition and may specifya brace-or-equal-initializer. If the member is declared with the constexpr specifier,it may be redeclared in namespace scope with no initializer (this usage is deprecated; see D.X).Declarations of other static data members shall not specify a brace-or-equal-initializer.”

Page 33: C++17 Key Features Summary - Ver 2

namespace A::B Nexon Talk 2017C++17

• 네임스페이스를중첩해서사용할 수 있는기능// until C++14namespace A

namespace B

namespace C

// ...

// since C++17namespace A::B::C

// ...

Page 34: C++17 Key Features Summary - Ver 2

Structured bindings Nexon Talk 2017C++17

• 드디어 사용할 수 있는다중반환! (사실은 Tuple-like objects…)using Coordinate = std::pair<int, int>;Coordinate origin()

return Coordinate 0, 0 ;

const auto[x, y] = origin();x; // == 0y; // == 0

Page 35: C++17 Key Features Summary - Ver 2

constexpr if Nexon Talk 2017C++17

• static if의 C++ 버전, 특정 블록만 컴파일할 수 있는기능template <typename T>constexpr bool isIntegral()

if constexpr (std::is_integral<T>::value)return true;

elsereturn false;

static_assert(isIntegral<int>() == true);static_assert(isIntegral<char>() == true);static_assert(isIntegral<double>() == false);struct S ;static_assert(isIntegral<S>() == false);

Page 36: C++17 Key Features Summary - Ver 2

if (init; condition) Nexon Talk 2017C++17

• if 문에 초기화구문을 포함할수 있는기능

→ 공통적으로사용하는코드 패턴을 단순화하고 스코프를타이트하게유지// until C++14

std::lock_guard<std::mutex> lk(mx);if (v.empty()) v.push_back(val);

// since C++17

if (std::lock_guard<std::mutex> lk(mx); v.empty())v.push_back(val);

Page 37: C++17 Key Features Summary - Ver 2

switch (init; condition) Nexon Talk 2017C++17

• switch 문에초기화 구문을 포함할수 있는기능

→ 공통적으로사용하는코드 패턴을 단순화하고 스코프를타이트하게유지// until C++14Foo gadget(args);

switch (auto s = gadget.status())case OK:

gadget.zip();break;

case Bad:throw BadFoo(s.message());

// since C++17switch (Foo gadget(args);

auto s = gadget.status())case OK:

gadget.zip();break;

case Bad:throw BadFoo(s.message());

Page 38: C++17 Key Features Summary - Ver 2

std::any Nexon Talk 2017C++17

• Boost.any 기반라이브러리

• 모든 종류의 정보를 저장 (단, 복사 생성자를 지원해야함)

• any_cast()를 통해 원하는타입으로변환된결과를 얻을 수 있음

void foo(std::any a)

double d = std::any_cast<double>(a);std::cout << d << std::endl;

int main()

foo(3.4);

Page 39: C++17 Key Features Summary - Ver 2

std::optional Nexon Talk 2017C++17

• Boost.optional 기반라이브러리

• 함수에서 “유효하지않은 값”을 리턴하기위해만들어짐std::optional<int> Sqrt(int x)

if (x < 0)return std::optional<int>();

int i = 0;for (i = 0; i * i <= x; ++i) return std::optional<int>(i - 1);

int main()

for (int i = -5; i <= 5; ++i) std::optional<int> x = Sqrt(i);

if (x)std::cout << *x << std::endl;

elsestd::cout << "Invalid\n";

Page 40: C++17 Key Features Summary - Ver 2

std::variant Nexon Talk 2017C++17

• Boost.variant 기반라이브러리

• 타입세이프한 union을 나타냄

• boost::any와는다르게지정된형태로만될 수 있으며,

타입변환 시 동적 할당을사용하지않기에 성능이 좀 더 뛰어남std::variant<int, double> v 12 ;std::get<int>(v); // == 12std::get<0>(v); // == 12v = 12.0;std::get<double>(v); // == 12.0std::get<1>(v); // == 12.0

Page 41: C++17 Key Features Summary - Ver 2

std::variant Nexon Talk 2017C++17

• Example : State Machinestruct Connection

std::string m_serverAddress;

struct Disconnected ;struct Connecting ;struct Connected

std::chrono::system_clock::time_point m_connectedTime;std::optional<std::chrono::milliseconds> m_lastPingTime;

;struct ConnectionInterrupted

std::chrono::system_clock::time_point m_disconnectedTime;;

variant<Disconnected, Connecting,Connected, ConnectionInterrupted> m_connection;

;

Page 42: C++17 Key Features Summary - Ver 2

std::variant Nexon Talk 2017C++17

• Example : State Machineusing State = std::variant<Disconnected, Connecting,

Connected, ConnectionInterrupted>;

struct InterruptedEvent InterruptedEvent(Connection& c) : m_c(c) State operator()(const Disconnected&) return Disconnected(); State operator()(const Connecting&) return Disconnected(); State operator()(const Connected&)

const auto now = std::chrono::system_clock::now();m_c.notifyInterrupted(now);return ConnectionInterrupted now ;

State operator()(const ConnectionInterrupted& s) return s;

private:Connection& m_c;

;

Page 43: C++17 Key Features Summary - Ver 2

std::string_view Nexon Talk 2017C++17

• 문자열에대해 소유하지않는 레퍼런스

• 다른 어딘가에서소유하고있는문자열의 복사를 피하기위함

• 문자열상단에추상화를제공하는데 유용하게사용 (예 : 파싱)

std::string str " trim me" ;std::string_view v str ;v.remove_prefix(std::min(v.find_first_not_of(" "), v.size()));str; // == " trim me“v; // == "trim me"

Page 44: C++17 Key Features Summary - Ver 2

std::invoke Nexon Talk 2017C++17

• 함수와인자를받아 대신 실행해주는함수template <typename Callable>class Proxy

Callable c;public:

Proxy(Callable c) : c(c) template <class... Args>decltype(auto) operator()(Args&&... args)

return std::invoke(c, std::forward<Args>(args)...);

;

auto add = [](int x, int y) return x + y; ;Proxy<decltype(add)> p add ;p(1, 2); // == 3

Page 45: C++17 Key Features Summary - Ver 2

std::apply Nexon Talk 2017C++17

• std::invoke와 똑같은 동작을 하는함수

• 차이점이라면가변인자로받지않고 std::tuple로 받음auto add = [](int x, int y) return x + y; ;std::apply(add, std::make_tuple(1, 2)); // == 3

void print(std::string i, std::string j)

std::cout << i << " " << j << std::endl;

std::tuple<std::string, std::string> t "ab", "cd" ;std::apply(print, t);

Page 46: C++17 Key Features Summary - Ver 2

std::map<std::string, std::string> userMap;

userMap.insert(std::make_pair("Kim123", "Kim"));userMap.emplace("Lee123", "Lee");userMap.try_emplace("Yun123", "Yun");

std::map::try_emplace Nexon Talk 2017C++17

• 키와값을 모두 메모리에 직접 생성하는함수

(std::map::insert와 std::map::emplace와는다름)

• 키가 이미 존재하는경우, 아무일도하지않음

Page 47: C++17 Key Features Summary - Ver 2

std::map::insert_or_assign Nexon Talk 2017C++17

• 키가 존재하지않는 경우, std::map::insert처럼 새값을 삽입

• 키가 존재하는 경우, std::forward<Value>(obj)를할당

std::map<char, int> mp 'B', 1256 ;

mp.insert_or_assign('A', 890); // The data is inserted since no key with ‘A’// exist in the container

for (auto elem : mp)

std::cout << elem.first << " " << elem.second << std::endl;

mp.insert_or_assign('B', 7584); // 7584 is assigned to the value of the pair// with the key as ‘B’

std::cout << mp['B'] << std::endl; // Returns the newly assign value

Page 48: C++17 Key Features Summary - Ver 2

Filesystem TS v1 Nexon Talk 2017C++17

• Boost.filesystem 기반라이브러리

• 파일, 경로, 디렉터리와관련된작업들을 수행할수 있음

namespace fs = std::experimental::filesystem;

int main() fs::create_directories("sandbox/a/b");std::ofstream("sandbox/file1.txt");std::ofstream("sandbox/file2.txt");for (auto& p : fs::directory_iterator("sandbox"))

std::cout << p << '\n';fs::remove_all("sandbox");

Page 49: C++17 Key Features Summary - Ver 2

// sort with dynamically-selected executionsize_t threshold = 30;execution_policy exec = seq;

if (v.size() > threshold)

exec = par;

sort(exec, v.begin(), v.end());

Parallelism TS v1 Nexon Talk 2017C++17

• 순차적인 STL 처리→ 병렬적인 STL 처리vector<int> v = 1,2,3 ;

// standard sequential sortsort(v.begin(), v.end());

// explicitly sequential sortsort(seq, v.begin(), v.end());

// permitting parallel executionsort(par, v.begin(), v.end());

// permitting vectorization as wellsort(par_vec, v.begin(), v.end());

Page 50: C++17 Key Features Summary - Ver 2

Removed keywords Nexon Talk 2017C++17

• C++17부터 지원하지않는 키워드들// 1. registerregister int a;

// 2. bool incrementbool b = 0;++b; // bool increment

// 3. auto_ptrauto_ptr<int> ap;

// 4. random_shuffleint x[10] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;random_shuffle(x, x + 10);

Page 51: C++17 Key Features Summary - Ver 2

다루지 않은 C++17의새 기능 Nexon Talk 2017C++17

• Template argument deduction for class templates

• Declaring non-type template parameters with auto

• UTF-8 character literals

• Direct-list-initialization of enums

• std::byte type

• Splicing for maps and sets

• And so on…

Page 52: C++17 Key Features Summary - Ver 2

C++17 이후 논의중인기능들 Nexon Talk 2017C++17

• Unified call syntax

• operator. (Dot)

• Contract

• And so on…

Page 53: C++17 Key Features Summary - Ver 2

Unified call syntax Nexon Talk 2017C++17

• 함수호출문법의개선, .으로부터 봉인 해제!class Test public:

void foo(int a) ;

int main() vector<int> v1;vector<int> v2;v1.swap(v2);swap(v1, v2);

Test t;t.foo(1); // ok ..foo(t, 1); // ok in the future

Page 54: C++17 Key Features Summary - Ver 2

template<class X>class Refpublic:

Ref(int a) : p new X a X& operator.() /* maybe some code here */ return *p; ~Ref() delete p; void rebind(X* pp) delete p; p = pp; // ...

private:X* p;

;

Ref<X> x 99 ;x.f(); // means (x.operator.()).f() means (*x.p).f()x = X 9 ; // means x.operator.() = X9 means (*x.p) = X9

operator. (Dot) Nexon Talk 2017C++17

• .도 연산자오버로딩할 수 있는 시대! → “Smart Reference”

Page 55: C++17 Key Features Summary - Ver 2

Contract Nexon Talk 2017C++17

• 우리는 늘 버그와싸운다!

Page 56: C++17 Key Features Summary - Ver 2

Contract Nexon Talk 2017C++17

• 그래서 우리가사용하는방법, assert()void print_number(int* myInt)

assert(myInt != nullptr);std::cout << *myInt << "\n";

int main()

int a = 10;int *b = nullptr, *c = nullptr;

b = &a;

print_number(b);print_number(c);

Page 57: C++17 Key Features Summary - Ver 2

Contract Nexon Talk 2017C++17

• 계약(Contract)이란, 함수앞에사전 조건과사후 조건을 추가해

assert()처럼 특정 조건을 만족하는지검사할수 있는기능

(assert()보다가독성이 좋아 더 직관적이다)

• 사전 조건 (Pre-condition) : expects

• 사후 조건 (Post-condition) : ensures

template<typename T>class ArrayView

T& operator[](size_t i)[[expects:i < size()]];

ArrayView(const vector<T>& v)[[ensures:data() == v.data()]];;

Page 58: C++17 Key Features Summary - Ver 2

struct A

bool f() const; bool g() const;virtual std::string bhar()[[expects:f() && g()]];virtual int hash()[[ensures:g()]];virtual void gash()[[expects:g()]];virtual double fash(int i) const[[expects:i > 0]];

;

struct B : A

std::string bhar() override[[expects:f()]]; // ERROR: weakening.int hash() override[[ensures:f() && g()]]; // ERROR: strengthening.void gash() override[[expects:g()]]; // OK: repeat from base.double fash(int) override; // OK: inherited from base.

;

Contract Nexon Talk 2017C++17

• Example : expects와 ensures의사용 방법이해

Page 59: C++17 Key Features Summary - Ver 2

C++17 이후 (아마) 추가될 TS Nexon Talk 2017C++17

• Concept TS

• Range TS

• Networking TS

• Coroutine TS

• Module TS

• Graphics TS

• Reflection TS

Page 60: C++17 Key Features Summary - Ver 2

Concept TS Nexon Talk 2017C++17

• 다음 코드의출력 결과는?#include <algorithm>#include <list>

int main()

std::list<int> l = 2, 1, 3 ;std::sort(l.begin(), l.end());

Page 61: C++17 Key Features Summary - Ver 2

Concept TS Nexon Talk 2017C++17

• 다음 코드의출력 결과는?

Page 62: C++17 Key Features Summary - Ver 2

Concept TS Nexon Talk 2017C++17

• 오류의발생원인

• template <class RandomIt>void sort(RandomIt first, RandomIt last);

• 여기서 RandomIt는 ValueSwappable과 RandomAccessIterator의제약 사항을 만족해야함

→ 하지만 int에는 반복자(Iterator)가 존재하지 않는다!

std::list<int> l = 2, 1, 3 ;std::sort(l.begin(), l.end());

Page 63: C++17 Key Features Summary - Ver 2

Concept TS Nexon Talk 2017C++17

• C#에서는제약사항과관련해다양한클래스와인터페이스를제공

• ICloneable

• IComparable

• IConvertible

• IFormattable

• Nullable

• …

• C++에서는? … → Concept의 등장!

Page 64: C++17 Key Features Summary - Ver 2

template <class T>concept bool EqualityComparable()

return requires(T a, T b) a == b->Boolean; // Boolean is the concept defininga != b->Boolean; // a type usable in boolean context

;

Concept TS Nexon Talk 2017C++17

• C++ 템플릿의확장기능→ 템플릿매개변수에제약을건다!

void f(const EqualityComparable&);

f("abc"s); // OK, std::string satisfies EqualityComparable// Error: not EqualityComparablef(std::use_facet<std::ctype<char>>(std::locale));

Page 65: C++17 Key Features Summary - Ver 2

Concept TS Nexon Talk 2017C++17

• 이제 컴파일러의오류 메시지가명확해진다!In instantiation of 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<int>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':error: no match for 'operator-' (operand types are 'std::_List_iterator<int>' and 'std::_List_iterator<int>')std::__lg(__last - __first) * 2,

error: cannot call function 'void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator<int>]'note: concept 'RandomAccessIterator()' was not satisfied

Page 66: C++17 Key Features Summary - Ver 2

Concept TS Nexon Talk 2017C++17

• Concept 리스트

• Basic

• DefaultConstructible, MoveConstructible, CopyConstructible,

MoveAssignable, CopyAssignable, Destructible

• Library-wide

• EqualityComparable, LessThanComparable, Swappable, ValueSwappable,

NullablePointer, Hash, Allocator, FunctionObject, Callable, Predicate,

• Iterator

• InputIterator, OutputIterator, ForwardIterator, BidirectionalIterator,

RandomAccessIterator, ContiguousIterator

Page 67: C++17 Key Features Summary - Ver 2

Range TS Nexon Talk 2017C++17

• 범위를다루는제너릭라이브러리

• 명세 문서 : https://ericniebler.github.io/std/wg21/D4128.html

• 구현 파일 : https://github.com/ericniebler/range-v3

• Range의장점

• 편의성 (Convenience) : 짧아지는 코드

• 느긋한 계산 (Lazy Evaluation) : 무한범위 표현 가능, 불필요한 계산 회피

• 조합성 (Composability) : 직관적인 표현 가능, 코드 생산성 향상

Page 68: C++17 Key Features Summary - Ver 2

Range TS Nexon Talk 2017C++17

• Example : [0 ~ 15) 에서 5개씩그룹을 지어 각 그룹의합을 구하기

• 0 + 1 + 2 + 3 + 4 = 10

• 5 + 6 + 7 + 8 + 9 = 35

• …

vector<int> v =view::iota(0, 15) |view::group_by(quotient) |view::transform(sum);

for (auto e : v)cout << e << " ";

cout << endl;

auto quotient = [](int a, int b) return a / 5 == b / 5;

;

auto sum = [](auto rng) return ranges::accumulaate(rng, 0);

;

Page 69: C++17 Key Features Summary - Ver 2

Range TS Nexon Talk 2017C++17

• Example : 피타고라스수

• 𝑎𝑎2 + 𝑏𝑏2 = 𝑐𝑐2 을 만족하는 세 자연수 쌍 𝑎𝑎, 𝑏𝑏, 𝑐𝑐 100개 구하기

auto triples = view::ints(1) >>= [] (int z) returnview::ints(1, z + 1) >>= [=](int x) returnview::ints(x, z + 1) >>= [=](int y) return

yield_if(x*x + y*y == z*z,std::make_tuple(x, y, z));

; ; ;

Page 70: C++17 Key Features Summary - Ver 2

Networking TS Nexon Talk 2017C++17

• Boost.asio 기반라이브러리

• 명세 문서 : https://github.com/chriskohlhoff/networking-ts

• 구현 파일 : https://github.com/chriskohlhoff/networking-ts-impl

try io_service io_service;tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));for (;;)

tcp::socket socket(io_service);acceptor.accept(socket);string message = make_daytime_string();boost::system::error_code ignored_error;boost::asio::write(socket, boost::asio::buffer(message), ignored_error);

catch (std::exception& e) std::cerr << e.what() << std::endl;

Page 71: C++17 Key Features Summary - Ver 2

Coroutine TS Nexon Talk 2017C++17

• Stackless Resumable Functions

• Lightweight, customizable coroutines

• Targeted to another technical specifications

• Experimental implementation in Visual Studio 2015 Update 1

• 2 × 2 × 2• 새로운 키워드 2개 : await, yield

• 새로운 컨셉 2개 : Awaitable, Coroutine Promise

• 새로운 타입 2개 : resumable_handle, resumable_traits

Page 72: C++17 Key Features Summary - Ver 2

Coroutine TS Nexon Talk 2017C++17

• Example 1 : 비동기작업 (Asynchronous Operations)// this could be some long running computation or I/Ofuture<int> CalculateTheAnswer()

return std::async([] this_thread::sleep_for(1s);return 42;

);

// Here is a resumable functionfuture<void> Coroutine()

std::cout << "Started waiting... \n";auto result = __await CalculateTheAnswer();std::cout << "Got " << result << "\n";

int main()

Coroutine().get();

Page 73: C++17 Key Features Summary - Ver 2

Coroutine TS Nexon Talk 2017C++17

• Example 2 : 제너레이터패턴 (Generator Pattern)generator<int> Fibonacci()

int a = 0;int b = 1;for (;;)

__yield_value a;auto next = a + b;a = b;b = next;

int main()

for (auto v : Fibonacci())

if (v > 50)break;

cout << v << endl;

Page 74: C++17 Key Features Summary - Ver 2

Module TS Nexon Talk 2017C++17

• C++에서는 #include를 통해 헤더 파일을포함

• 문제는 헤더 파일안에있는모든 부분을 포함한다는것!

(포함하고싶지않은 부분도가져오게 됨)

• 다른언어에서는 필요한 부분만가져올 수 있는기능을제공

• C# : using System.Linq;

• Java : import java.util.Scanner;

• Python : from path import pi

• C++에서는? … → Module의 등장!

Page 75: C++17 Key Features Summary - Ver 2

Module TS Nexon Talk 2017C++17

• 모듈에서기억해야할 3가지 키워드!

• module : 모듈로 정의할 이름을 지정

Ex) module M1 : 정의할 모듈의 이름은 M1이다.

• import : 가져올 모듈의 이름을 지정

Ex) import M1 : 가져올 모듈의 이름은 M1이다.

• export : 내보낼 함수의 인터페이스를 지정

Ex) export int f(int, int) :

내보낼 함수의 이름은 f이고 리턴 타입은 int, 매개 변수는 (int, int)다.

Page 76: C++17 Key Features Summary - Ver 2

Module TS Nexon Talk 2017C++17

• Example : 두 cpp 파일에서모듈을 정의해다른 cpp 파일에서사용

// m1.cppmodule M1;export int f(int, int);int g(int x) return x * x; int f(int x, int y) return g(x) + g(y);

// m2.cppmodule M2;export bool g(int, int);import std.math;int f(int x, int y) return x + y; int g(int x, int y)

return f(abs(x), abs(y));

// main.cppimport M1;import M2;import std.vector;

int main()

return f(3, 4) + g(3, 4);

Page 77: C++17 Key Features Summary - Ver 2

Graphics TS Nexon Talk 2017C++17

• 2D 그래픽렌더링 및 표시를 위한라이브러리

• 명세 문서 및 구현 파일 : https://github.com/mikebmcl/N3888_RefImpl

#include <experimental/io2d>using namespace std::experimental::io2d;

int main()

auto ds = make_display_surface(640, 480, format::argb32);ds.draw_callback([](display_surface& ds)

ds.paint(rgba_color::firebrick());ds.render_text("Hello world!", 50.0, 50.0 , rgba_color::aqua());

);

return ds.show();

Page 78: C++17 Key Features Summary - Ver 2

Reflection TS Nexon Talk 2017C++17

• 컴파일타임기반 Static Reflection

• 명세 문서 및 구현 파일 : https://github.com/matus-chochlik/mirror

typedef reflexpr(unsigned) meta_unsigned;static_assert(is_metaobject_v<meta_unsigned>, "");static_assert(meta::is_type_v<meta_unsigned>, "");static_assert(!meta::is_alias_v<meta_unsigned>, "");static_assert(is_same_v<

meta::get_reflected_type_t<meta_unsigned>,unsigned>, "");

static_assert(meta::has_name_v<meta_unsigned>, "");cout << meta::get_name_v<meta_unsigned> << endl;

typedef reflexpr(unsigned*) meta_ptr_unsigned;static_assert(meta::has_name_v<meta_ptr_unsigned>, "");cout << meta::get_name_v<meta_ptr_unsigned> << endl;

Page 79: C++17 Key Features Summary - Ver 2

Recommend C++ books Nexon Talk 2017C++17

• The C++ Programming Language, 4th Edition

• Effective Modern C++: 42 Specific Ways to Improve Your Use of

C++11 and C++14

• Discovering Modern C++

• The C++ Standard Library: A Tutorial and Reference (2nd Edition)

• Optimized C++: Proven Techniques for Heightened Performance

• C++ Concurrency in Action: Practical Multithreading

• A Tour of C++ (C++ In-Depth)

Page 80: C++17 Key Features Summary - Ver 2

Summary Nexon Talk 2017C++17

• C++17 표준화작업이완료되었습니다.

이제는 C++20을 향해…

• 소개한기능외에도다양한 추가 / 변경사항들이있습니다.

• 새기능이 추가되었다고 무조건다 알아야할 필요는 없습니다.

• 모던 C++의기능을 무조건 사용하기보다는,

어떤 기능인지파악하고필요한 곳에 적절히 사용합시다.

Page 81: C++17 Key Features Summary - Ver 2

References Nexon Talk 2017C++17

• http://www.cplusplus.com/reference

• http://en.cppreference.com

• http://www.isocpp.org

• http://www.open-std.org

• https://github.com/ericniebler/range-v3

• https://github.com/chriskohlhoff/networking-ts-impl

• https://github.com/mikebmcl/N3888_RefImpl

• https://github.com/matus-chochlik/mirror

Page 82: C++17 Key Features Summary - Ver 2

References Nexon Talk 2017C++17

• http://khuttun.github.io/2017/02/04/implementing-state-machines-

with-std-variant.html

• https://github.com/AnthonyCalandra/modern-cpp-features

• https://github.com/fffaraz/awesome-cpp

Page 83: C++17 Key Features Summary - Ver 2

감사합니다

http://github.com/utilForever질문 환영합니다!