[c++ korea] effective modern c++ study item 24-26

40
Effective Modern C++ Study C++ Korea

Upload: seok-joon-yun

Post on 30-Jul-2015

439 views

Category:

Software


2 download

TRANSCRIPT

Page 1: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea

Page 2: [C++ Korea] Effective Modern C++ Study item 24-26
Page 3: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 3

불필요한 복사를 줄이기

위해 레퍼런스로 받음.

R-Value는 받을 수 없음.

Page 4: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 4

Page 5: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea

w의 타입은 Widget&

w의 타입은 Widget&&

Page 6: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 6

• R-Value Reference • Universal Reference

std::vector<T>의 T는 param과 독립적.

Page 7: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 7

• Universal Reference 아님.

• R-Value만 받을 수 있다.

• 타입 추론이 발생

하지 않는다.

Page 8: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 8

Page 9: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 9

Page 10: [C++ Korea] Effective Modern C++ Study item 24-26
Page 11: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 11

Page 12: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 12

Page 13: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 13

Page 14: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 14

Page 15: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 15

Page 16: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 16

//지역변수 n이 w.setName으로 이동

Page 17: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 17

Page 18: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 18

Page 19: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 19

Page 20: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 20

Page 21: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 21

Page 22: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 22

Page 23: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 23

Page 24: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 24

Page 25: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 25

Page 26: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 26

Page 27: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 27

RVO

Page 28: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 28

A : 조건 2에 부합하지 않음

Page 29: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 29

Page 30: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 30

Page 31: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 31

Page 32: [C++ Korea] Effective Modern C++ Study item 24-26
Page 33: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 33

std::multiset<std::string> History; // Global Log History

void Log(const std::string& item)

{

History.emplace(item);

}

std::string name("Luna"); Log(name);

Log(std::string("Star"));

Log("Seokjoon");

// Parameter로 name이라는 변수가 사용됨. // L-Value가 emplace로 COPY

// Parameter로 R-Value가 전달되었지만, // item이 L-Value라서 결국 emplace로 COPY

// Parameter로 R-Value가 전달되었지만, // 임시로 std::string 개체가 만들어져서 결국 emplace로 COPY

Universal Reference + std::forward 면 efficient하게 할 수 있다.

Page 34: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 34

std::multiset<std::string> History; // Global Log History

template<typename T>

void Log(T&& item)

{

History.emplace(std::forward<T>(item));

}

std::string name("Luna"); Log(name);

Log(std::string("Star"));

Log("Seokjoon");

// L-Value std::string를 emplace로 COPY (기존과 동일)

// R-Value를 emplace로 MOVE

// std::string를 item에서 임시로 만드는 것이 아니라 // multiset 안에다가 직접 생성함

하지만 std::string가 아닌 Indirect로 값을 받아야 할 경우가 있다면 ???

Page 35: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 35

std::string GetItemFromTable(int idx);

void Log(int idx)

{

History.emplace(GetItemFromTable( ));

}

Log(22);

short s = 22;

Log(s);

// Call int overload

// Compile Error : // can’t convert argument // ‘short’ to std::string ctor

Universal Reference Overload 함수는 C++에서 가장 탐욕스러운 함수이다. (닥치는 대로 호로록)

• Instantiation of template (자세한 설명 생략)

• Overload Resolution Rule (자세한 설명 생략)

(위 2가지에 대해서 모른다면 검색해서 알아 보도록… Right Now !!!)

• Parameter가 int인 경우 정확히 int Overload 함수를 실행하지만,

• short인 경우는 T&&을 이용하여 Instantiation이 가능하다.

• Overload Resolution Rule에 의해서 template 함수가 호출되며,

Compile Error를 발생시킨다.

해결방법은 ? Perfect Forwarding Constructor (라고는 하는데 이번 item에서는 해결이 안된다.)

Page 36: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 36

class Item {public:

template<typename T>

explicit Item(T&& data) // Perfect Forwarding ctor

: value(std::forward<T>(data)) {}

explicit Item(int idx) // int ctor

: value(GetItemFromTable(idx)) {}

private:

std::string value;

};

• 하지만, int를 제외한 나머지 타입 (std::size_t, short, long …)에 대해서는 Universal Reference Constructor가 호출

• 심지어 생성자에 다른 Item 개체를 넣어도 Universal Reference Constructor 생성자가 ???

아 왜 ?

Page 37: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 37

Item ME("Luna");

auto CloneofME(ME);

Item(const Item& SRC); // Copy ctor (Compiler-generated)

Item(Item&& SRC); // Move ctor (Compiler-generated)

explicit Item(Item& ) // Instantiated from Perfect Forwarding template: value(std::forward<Item&>(data)) {}

• Overload Resolution Rule에 따라 본다면, 뭐가 가장 parameter에 똑같이 매칭될까 ?

• 그럼 해결 방법은 ?

Compiler는 C++의 Rule을 반드시 지키도록 맹세하였다. (융통성 없는 놈하고는…)

const Item ME("Luna"); // Object is now const

auto CloneofME(ME);

Page 38: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 38

class ItemEx : public Item {public:

ItemEx(const ItemEx& item) // Copy ctor

: Item(item) {} // Calls base class forward ctor

ItemEx(ItemEx&& item) // Move ctor

: Item(std::move(item)) {} // Calls base class forward ctor

};

• Derived Class에서 Base Class로 Item이 아닌 ItemEx로 전달하기 때문이다.

Page 39: [C++ Korea] Effective Modern C++ Study item 24-26

Effective Modern C++ Study C++ Korea 39

• Universal Reference를 Overload하면 뭘 상상하든 그 이상으로

훨씬 더 자주 맨날맨날 허구언날 시도때도 없이

Universal Reference Overload가 호출된다.

• Perfect Forwarding Constructor도 마찬가지다. 아니 이놈은 더하다.

non-const L-Value와의 궁합이 COPY Constructor보다 더 잘 맞고,

Derived class의 COPY, MOVE Constructor의 호출도 가로채버린다.

• 그냥 Universal Reference Overload 와 Perfect Forwarding Constructor를 쓰지마라.