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
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
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
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
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
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
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
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
50. Effective Modern C++ Study
C++ Korea
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i)
{
authenticateUser();
return c[i];
}
50
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
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