Effective Modern C++ Study
C++ Korea
Effective Modern C++ Study
C++ Korea3
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(ParamType param);
f(expr);
4
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(const T& param);
int x = 0;
f(expr);
// ParamType은 const T&
5
Effective Modern C++ Study
C++ Korea6
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T& param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x); // T의 타입은 int
// param의 타입은 int&
// T의 타입은 const int
// param의 타입은 const int&
// T의 타입은 const int
// param의 타입은 const int&
f(cx);
f(rx);
8
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(const T& param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x); // T의 타입은 int
// param의 타입은 const int&
// T의 타입은 int
// param의 타입은 const int&
// T의 타입은 int
// param의 타입은 const int&
f(cx);
f(rx);
9
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T* param);
int x = 27;
const int* px = &x;
f(&x); // T의 타입은 int
// param의 타입은 int*
// T의 타입은 const int
// param의 타입은 const int*
f(px);
10
Effective Modern C++ Study
C++ Korea12
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T&& param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x); // x는 Lvalue, T의 타입은 int&
// param의 타입 또한 int&
// cx는 Lvalue, T의 타입은 const int&
// param의 타입 또한 const int&
f(cx);
f(rx); // rx는 Lvalue, T의 타입은 const int&
// param의 타입 또한 const int&
f(27); // 27은 Rvalue, T의 타입은 int
// 따라서 param의 타입은 int&&
13
Effective Modern C++ Study
C++ Korea15
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T param);
int x = 27;
const int cx = x;
const int& rx = x;
f(x); // T와 param의 타입은 둘 다 int
// T와 param의 타입은 둘 다 intf(cx);
f(rx); // T와 param의 타입은 둘 다 int
param은 cx 및 rx와 다른 오브젝트!
따라서 param이 무엇이든 cx와 rx는 수정할 수 없음
16
Effective Modern C++ Study
C++ Korea17
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T param);
const char* const ptr =
“Fun with pointers”;
f(ptr);
18
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T param);
const char* const ptr =
“Fun with pointers”;
f(ptr);
19
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T param);
const char* const ptr =
“Fun with pointers”;
f(ptr);
20
Effective Modern C++ Study
C++ Korea
const char name[] = “J. P. Briggs”; // name의 타입은 const char[13]
const char* ptrToName = name; // 배열이 포인터로 붕괴됨
여기서, const char* 타입인 ptrToName은
const char[13] 타입인 name으로 초기화됨
const char*와 const char[13]은 서로 같은 타입이 아니지만,
배열 – 포인터 붕괴 규칙으로 인해 컴파일됨
22
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T param);
const char name[] = “J. P. Briggs”;
f(name); // T와 param에 대해 어떤 타입으로 추론될까?
23
Effective Modern C++ Study
C++ Korea
f(name); // name은 배열이지만, T는 const char*로 추론됨
24
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(T& param);
const char name[] = “J. P. Briggs”;
f(name); // T와 param에 대해 어떤 타입으로 추론될까?
25
Effective Modern C++ Study
C++ Korea
template<typename T, std::size_t N>
constexpr std::size_t arraySize(T(&)[N]) noexcept {
return N;
}
int keyVals[] = {1, 3, 7, 9, 11, 22, 35};
int mappedVals[arraySize(keyVals)];
std::array<int, arraySize(keyVals)> mappedVals;
// constexpr을 선언하면
// 컴파일하는 동안 작업을 처리함
// noexcept를 선언하면
// 컴파일러가 좋은 코드를 생성함
// 모던 C++에서는 std::array를 사용하는 것이 좋음
26
Effective Modern C++ Study
C++ Korea
void someFunc(int, double); // someFunc는 함수
// 타입은 void(int, double)
template<typename T>
void f1(T param);
template<typename T>
void f2(T& param);
// f1은 값에 의한 전달
// f2는 레퍼런스에 의한 전달
f1(someFunc);
f2(someFunc);
// 타입은 void(*)(int, double)
// 타입은 void(&)(int, double)
28
Effective Modern C++ Study
C++ Korea29
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(ParamType param);
f(expr);
템플릿 타입 추론
auto x = 27;
const auto cx = x;
const auto& rx = x;
auto 타입 추론
직접 매핑 (Direct Mapping)
31
Effective Modern C++ Study
C++ Korea
template<typename T>
void func_for_x(T param);
func_for_x(27);
template<typename T>
void func_for_cx(const T param);
func_for_cx(x);
template<typename T>
void func_for_rx(const T& param);
func_for_rx(x);
auto x = 27;
(타입 지정자 : auto)
const auto cx = x;
(타입 지정자 : const auto)
const auto& rx = x;
(타입 지정자 : const auto&)
32
Effective Modern C++ Study
C++ Korea33
Effective Modern C++ Study
C++ Korea
auto x = 27; // 경우 3
// x는 포인터 또는 레퍼런스가 아님
// 경우 3
// cx는 포인터 또는 레퍼런스가 아님
// 경우 1
// rx는 유니버셜 레퍼런스가 아닌 레퍼런스임
const auto cx = x;
const auto& rx = x;
34
Effective Modern C++ Study
C++ Korea
auto&& uref1 = x; // x는 int이며 Lvalue
// 따라서 uref1의 타입은 int&
// cx는 const int이며 Lvalue
// 따라서 uref2의 타입은 const int&
// 27은 int이며 Rvalue
// 따라서 uref3의 타입은 int&&
auto&& uref2 = cx;
auto&& uref3 = 27;
35
Effective Modern C++ Study
C++ Korea
// func1의 타입은
// void(*)(int, double)
const char name[] =
“R. N. Briggs”;
// name의 타입은 const char[13]
auto arr1 = name;
auto& arr2 = name;
void someFunc(int, double);
auto func1 = someFunc;
auto& func2 = someFunc;
// arr1의 타입은 const char*
// arr2의 타입은 const char(&)[13]
// func2의 타입은
// void(&)(int, double)
// someFunc는 함수
// 타입은 void(int, double)
36
Effective Modern C++ Study
C++ Korea37
Effective Modern C++ Study
C++ Korea38
Effective Modern C++ Study
C++ Korea39
Effective Modern C++ Study
C++ Korea
auto x = {11, 23, 9};
template<typename T>
void f(T param);
// x의 타입은 std::initializer_list<int>
// 매개변수가 있는 템플릿의 선언은
// x의 선언와 동일함
f({11, 23, 9}); // 오류! T의 타입을 추론할 수 없음
40
Effective Modern C++ Study
C++ Korea
template<typename T>
void f(std::initializer_list<T> initList);
f({11, 23, 9}); // T는 int로 추론
// initList의 타입은 std::initializer_list<int>
41
Effective Modern C++ Study
C++ Korea
auto createInitList()
{
return {1, 2, 3};
}
// 오류 : 타입을 추론할 수 없음
42
Effective Modern C++ Study
C++ Korea
std::vector<int> v;
…
auto resetV =
[&v](const auto& newValue) { v = newValue; };
…
resetV({1, 2, 3}); // 오류 : 타입을 추론할 수 없음
43
Effective Modern C++ Study
C++ Korea44
Effective Modern C++ Study
C++ Korea
const int i = 0; // decltype(i)는 const int
bool f(const Widget& w); // decltype(w)는 const Widget&
// decltype(f)는 bool(const Widget&)
struct Point {
int x, y;
};
// decltype(Point::x)는 int
// decltype(Point::y)는 int
Widget w; // decltype(w)는 Widget
if (f(w)) // decltype(f(w))는 bool
46
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i)
-> decltype(c[i])
{
authenticateUser();
return c[i];
}
함수 이름 전에 있는 auto는 타입 추론과 아무 관련 없음
47
Effective Modern C++ Study
C++ Korea48
Effective Modern C++ Study
C++ Korea49
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i)
{
authenticateUser();
return c[i];
}
50
Effective Modern C++ Study
C++ Korea51
Effective Modern C++ Study
C++ Korea
std::deque<int> d;
…
authAndAccess(d, 5) = 10; // d[5] = 10, 컴파일 오류 발생!
52
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container& c, Index i) {
authenticateUser();
return c[i];
}
53
Effective Modern C++ Study
C++ Korea
Widget w;
const Widget& cw = w;
auto myWidget1 = cw;
decltype(auto) myWidget2 = cw;
// auto 타입 추론
// myWidget1의 타입은 Widget
// decltype 타입 추론
// myWidget2의 타입은
// const Widget&
54
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container& c, Index i);
55
Effective Modern C++ Study
C++ Korea
std::deque<std::string> makeStringDeque(); // 팩토리 함수
auto s = authAndAccess(makeStringDeque(), 5);
56
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container&& c, Index i);
57
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container&& c, Index i)
{
authenticateUser();
return std::forward<Container>(c)[i];
}
58
Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
auto authAndAccess(Container&& c, Index i)
-> decltype(std::forward<Container>(c)[i])
{
authenticateUser();
return std::forward<Container>(c)[i];
}
59
Effective Modern C++ Study
C++ Korea60
Effective Modern C++ Study
C++ Korea61
Effective Modern C++ Study
C++ Korea
declrtype(auto) f1()
{
int x = 0;
return x;
}
declrtype(auto) f2()
{
int x = 0;
return (x);
}
// decltype(x)는 int
// 따라서 f1는 int를 반환
// decltype((x))는 int&
// 따라서 f2는 int&를 반환
62
Effective Modern C++ Study
C++ Korea
(expr == NAME*) ? AS DECLARED :
(expr == lvalue) ? T& :
// rvalue
(expr == xvalue) ? T&& : T // prvalue
* NAME: plain, unparenthesised variable, function - parameter, class member access
63
Effective Modern C++ Study
C++ Korea
* xvalue:
- function call where the function’s return value is
declared as and rvalue reference
e.g. std:move(x)
- static cast to an rvalue reference
e.g. static_cast<A&&>(a)
- a member access of an xvalue
e.g. static_cast<A&&>(a)).m_x
* prvalue: all other rvalues than above cases
64
Effective Modern C++ Study
C++ Korea65

[C++ Korea] Effective Modern C++ Study, Item 1 - 3

  • 1.
    Effective Modern C++Study C++ Korea
  • 3.
    Effective Modern C++Study C++ Korea3
  • 4.
    Effective Modern C++Study C++ Korea template<typename T> void f(ParamType param); f(expr); 4
  • 5.
    Effective Modern C++Study C++ Korea template<typename T> void f(const T& param); int x = 0; f(expr); // ParamType은 const T& 5
  • 6.
    Effective Modern C++Study C++ Korea6
  • 8.
    Effective Modern C++Study C++ Korea template<typename T> void f(T& param); int x = 27; const int cx = x; const int& rx = x; f(x); // T의 타입은 int // param의 타입은 int& // T의 타입은 const int // param의 타입은 const int& // T의 타입은 const int // param의 타입은 const int& f(cx); f(rx); 8
  • 9.
    Effective Modern C++Study C++ Korea template<typename T> void f(const T& param); int x = 27; const int cx = x; const int& rx = x; f(x); // T의 타입은 int // param의 타입은 const int& // T의 타입은 int // param의 타입은 const int& // T의 타입은 int // param의 타입은 const int& f(cx); f(rx); 9
  • 10.
    Effective Modern C++Study C++ Korea template<typename T> void f(T* param); int x = 27; const int* px = &x; f(&x); // T의 타입은 int // param의 타입은 int* // T의 타입은 const int // param의 타입은 const int* f(px); 10
  • 12.
    Effective Modern C++Study C++ Korea12
  • 13.
    Effective Modern C++Study C++ Korea template<typename T> void f(T&& param); int x = 27; const int cx = x; const int& rx = x; f(x); // x는 Lvalue, T의 타입은 int& // param의 타입 또한 int& // cx는 Lvalue, T의 타입은 const int& // param의 타입 또한 const int& f(cx); f(rx); // rx는 Lvalue, T의 타입은 const int& // param의 타입 또한 const int& f(27); // 27은 Rvalue, T의 타입은 int // 따라서 param의 타입은 int&& 13
  • 15.
    Effective Modern C++Study C++ Korea15
  • 16.
    Effective Modern C++Study C++ Korea template<typename T> void f(T param); int x = 27; const int cx = x; const int& rx = x; f(x); // T와 param의 타입은 둘 다 int // T와 param의 타입은 둘 다 intf(cx); f(rx); // T와 param의 타입은 둘 다 int param은 cx 및 rx와 다른 오브젝트! 따라서 param이 무엇이든 cx와 rx는 수정할 수 없음 16
  • 17.
    Effective Modern C++Study C++ Korea17
  • 18.
    Effective Modern C++Study C++ Korea template<typename T> void f(T param); const char* const ptr = “Fun with pointers”; f(ptr); 18
  • 19.
    Effective Modern C++Study C++ Korea template<typename T> void f(T param); const char* const ptr = “Fun with pointers”; f(ptr); 19
  • 20.
    Effective Modern C++Study C++ Korea template<typename T> void f(T param); const char* const ptr = “Fun with pointers”; f(ptr); 20
  • 22.
    Effective Modern C++Study C++ Korea const char name[] = “J. P. Briggs”; // name의 타입은 const char[13] const char* ptrToName = name; // 배열이 포인터로 붕괴됨 여기서, const char* 타입인 ptrToName은 const char[13] 타입인 name으로 초기화됨 const char*와 const char[13]은 서로 같은 타입이 아니지만, 배열 – 포인터 붕괴 규칙으로 인해 컴파일됨 22
  • 23.
    Effective Modern C++Study C++ Korea template<typename T> void f(T param); const char name[] = “J. P. Briggs”; f(name); // T와 param에 대해 어떤 타입으로 추론될까? 23
  • 24.
    Effective Modern C++Study C++ Korea f(name); // name은 배열이지만, T는 const char*로 추론됨 24
  • 25.
    Effective Modern C++Study C++ Korea template<typename T> void f(T& param); const char name[] = “J. P. Briggs”; f(name); // T와 param에 대해 어떤 타입으로 추론될까? 25
  • 26.
    Effective Modern C++Study C++ Korea template<typename T, std::size_t N> constexpr std::size_t arraySize(T(&)[N]) noexcept { return N; } int keyVals[] = {1, 3, 7, 9, 11, 22, 35}; int mappedVals[arraySize(keyVals)]; std::array<int, arraySize(keyVals)> mappedVals; // constexpr을 선언하면 // 컴파일하는 동안 작업을 처리함 // noexcept를 선언하면 // 컴파일러가 좋은 코드를 생성함 // 모던 C++에서는 std::array를 사용하는 것이 좋음 26
  • 28.
    Effective Modern C++Study C++ Korea void someFunc(int, double); // someFunc는 함수 // 타입은 void(int, double) template<typename T> void f1(T param); template<typename T> void f2(T& param); // f1은 값에 의한 전달 // f2는 레퍼런스에 의한 전달 f1(someFunc); f2(someFunc); // 타입은 void(*)(int, double) // 타입은 void(&)(int, double) 28
  • 29.
    Effective Modern C++Study C++ Korea29
  • 31.
    Effective Modern C++Study C++ Korea template<typename T> void f(ParamType param); f(expr); 템플릿 타입 추론 auto x = 27; const auto cx = x; const auto& rx = x; auto 타입 추론 직접 매핑 (Direct Mapping) 31
  • 32.
    Effective Modern C++Study C++ Korea template<typename T> void func_for_x(T param); func_for_x(27); template<typename T> void func_for_cx(const T param); func_for_cx(x); template<typename T> void func_for_rx(const T& param); func_for_rx(x); auto x = 27; (타입 지정자 : auto) const auto cx = x; (타입 지정자 : const auto) const auto& rx = x; (타입 지정자 : const auto&) 32
  • 33.
    Effective Modern C++Study C++ Korea33
  • 34.
    Effective Modern C++Study C++ Korea auto x = 27; // 경우 3 // x는 포인터 또는 레퍼런스가 아님 // 경우 3 // cx는 포인터 또는 레퍼런스가 아님 // 경우 1 // rx는 유니버셜 레퍼런스가 아닌 레퍼런스임 const auto cx = x; const auto& rx = x; 34
  • 35.
    Effective Modern C++Study C++ Korea auto&& uref1 = x; // x는 int이며 Lvalue // 따라서 uref1의 타입은 int& // cx는 const int이며 Lvalue // 따라서 uref2의 타입은 const int& // 27은 int이며 Rvalue // 따라서 uref3의 타입은 int&& auto&& uref2 = cx; auto&& uref3 = 27; 35
  • 36.
    Effective Modern C++Study C++ Korea // func1의 타입은 // void(*)(int, double) const char name[] = “R. N. Briggs”; // name의 타입은 const char[13] auto arr1 = name; auto& arr2 = name; void someFunc(int, double); auto func1 = someFunc; auto& func2 = someFunc; // arr1의 타입은 const char* // arr2의 타입은 const char(&)[13] // func2의 타입은 // void(&)(int, double) // someFunc는 함수 // 타입은 void(int, double) 36
  • 37.
    Effective Modern C++Study C++ Korea37
  • 38.
    Effective Modern C++Study C++ Korea38
  • 39.
    Effective Modern C++Study C++ Korea39
  • 40.
    Effective Modern C++Study C++ Korea auto x = {11, 23, 9}; template<typename T> void f(T param); // x의 타입은 std::initializer_list<int> // 매개변수가 있는 템플릿의 선언은 // x의 선언와 동일함 f({11, 23, 9}); // 오류! T의 타입을 추론할 수 없음 40
  • 41.
    Effective Modern C++Study C++ Korea template<typename T> void f(std::initializer_list<T> initList); f({11, 23, 9}); // T는 int로 추론 // initList의 타입은 std::initializer_list<int> 41
  • 42.
    Effective Modern C++Study C++ Korea auto createInitList() { return {1, 2, 3}; } // 오류 : 타입을 추론할 수 없음 42
  • 43.
    Effective Modern C++Study C++ Korea std::vector<int> v; … auto resetV = [&v](const auto& newValue) { v = newValue; }; … resetV({1, 2, 3}); // 오류 : 타입을 추론할 수 없음 43
  • 44.
    Effective Modern C++Study C++ Korea44
  • 46.
    Effective Modern C++Study C++ Korea const int i = 0; // decltype(i)는 const int bool f(const Widget& w); // decltype(w)는 const Widget& // decltype(f)는 bool(const Widget&) struct Point { int x, y; }; // decltype(Point::x)는 int // decltype(Point::y)는 int Widget w; // decltype(w)는 Widget if (f(w)) // decltype(f(w))는 bool 46
  • 47.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> auto authAndAccess(Container& c, Index i) -> decltype(c[i]) { authenticateUser(); return c[i]; } 함수 이름 전에 있는 auto는 타입 추론과 아무 관련 없음 47
  • 48.
    Effective Modern C++Study C++ Korea48
  • 49.
    Effective Modern C++Study C++ Korea49
  • 50.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> auto authAndAccess(Container& c, Index i) { authenticateUser(); return c[i]; } 50
  • 51.
    Effective Modern C++Study C++ Korea51
  • 52.
    Effective Modern C++Study C++ Korea std::deque<int> d; … authAndAccess(d, 5) = 10; // d[5] = 10, 컴파일 오류 발생! 52
  • 53.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> decltype(auto) authAndAccess(Container& c, Index i) { authenticateUser(); return c[i]; } 53
  • 54.
    Effective Modern C++Study C++ Korea Widget w; const Widget& cw = w; auto myWidget1 = cw; decltype(auto) myWidget2 = cw; // auto 타입 추론 // myWidget1의 타입은 Widget // decltype 타입 추론 // myWidget2의 타입은 // const Widget& 54
  • 55.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> decltype(auto) authAndAccess(Container& c, Index i); 55
  • 56.
    Effective Modern C++Study C++ Korea std::deque<std::string> makeStringDeque(); // 팩토리 함수 auto s = authAndAccess(makeStringDeque(), 5); 56
  • 57.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> decltype(auto) authAndAccess(Container&& c, Index i); 57
  • 58.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> decltype(auto) authAndAccess(Container&& c, Index i) { authenticateUser(); return std::forward<Container>(c)[i]; } 58
  • 59.
    Effective Modern C++Study C++ Korea template<typename Container, typename Index> auto authAndAccess(Container&& c, Index i) -> decltype(std::forward<Container>(c)[i]) { authenticateUser(); return std::forward<Container>(c)[i]; } 59
  • 60.
    Effective Modern C++Study C++ Korea60
  • 61.
    Effective Modern C++Study C++ Korea61
  • 62.
    Effective Modern C++Study C++ Korea declrtype(auto) f1() { int x = 0; return x; } declrtype(auto) f2() { int x = 0; return (x); } // decltype(x)는 int // 따라서 f1는 int를 반환 // decltype((x))는 int& // 따라서 f2는 int&를 반환 62
  • 63.
    Effective Modern C++Study C++ Korea (expr == NAME*) ? AS DECLARED : (expr == lvalue) ? T& : // rvalue (expr == xvalue) ? T&& : T // prvalue * NAME: plain, unparenthesised variable, function - parameter, class member access 63
  • 64.
    Effective Modern C++Study C++ Korea * xvalue: - function call where the function’s return value is declared as and rvalue reference e.g. std:move(x) - static cast to an rvalue reference e.g. static_cast<A&&>(a) - a member access of an xvalue e.g. static_cast<A&&>(a)).m_x * prvalue: all other rvalues than above cases 64
  • 65.
    Effective Modern C++Study C++ Korea65