<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>deulee의 개발 노트</title>
    <link>https://deulee.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 15 Aug 2026 13:32:53 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>deulee</managingEditor>
    <item>
      <title>원티드 포텐업 게임 클라이언트 지원</title>
      <link>https://deulee.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요,&amp;nbsp;저는&amp;nbsp;언리얼&amp;nbsp;엔진을&amp;nbsp;이용해&amp;nbsp;게임&amp;nbsp;개발을&amp;nbsp;진행하며&amp;nbsp;주로&amp;nbsp;네트워크&amp;nbsp;부분을&amp;nbsp;담당하고&amp;nbsp;있습니다.&amp;nbsp;엔진&amp;nbsp;코드를&amp;nbsp;분석하고&amp;nbsp;디버깅하면서&amp;nbsp;독학으로&amp;nbsp;실력을&amp;nbsp;쌓아왔지만,&amp;nbsp;실무에서&amp;nbsp;올바른&amp;nbsp;접근을&amp;nbsp;하고&amp;nbsp;있는지에&amp;nbsp;대한&amp;nbsp;확신이&amp;nbsp;부족해&amp;nbsp;고민이&amp;nbsp;많았습니다.&amp;nbsp;특히&amp;nbsp;네트워크&amp;nbsp;최적화,&amp;nbsp;멀티플레이&amp;nbsp;기능&amp;nbsp;구현,&amp;nbsp;타이밍&amp;nbsp;오류&amp;nbsp;해결에&amp;nbsp;적합한&amp;nbsp;설계를&amp;nbsp;하고&amp;nbsp;있는지에&amp;nbsp;대해&amp;nbsp;피드백을&amp;nbsp;받을&amp;nbsp;기회가&amp;nbsp;부족했습니다.&amp;nbsp;또한,&amp;nbsp;체계적인&amp;nbsp;게임&amp;nbsp;개발&amp;nbsp;프로세스를&amp;nbsp;배우고&amp;nbsp;적용할&amp;nbsp;기회가&amp;nbsp;부족해&amp;nbsp;어려움을&amp;nbsp;겪은&amp;nbsp;경험도&amp;nbsp;있으며,&amp;nbsp;이로&amp;nbsp;인해&amp;nbsp;스스로의&amp;nbsp;부족함을&amp;nbsp;절실히&amp;nbsp;느꼈습니다. &lt;br /&gt;&lt;br /&gt;원티드&amp;nbsp;포텐업의&amp;nbsp;커리큘럼과&amp;nbsp;멘토님들의&amp;nbsp;도움을&amp;nbsp;통해&amp;nbsp;부족한&amp;nbsp;지식을&amp;nbsp;보완하고,&amp;nbsp;실무에&amp;nbsp;적용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;능력을&amp;nbsp;키워&amp;nbsp;효율적이고&amp;nbsp;발전된&amp;nbsp;개발자로&amp;nbsp;성장하고&amp;nbsp;싶습니다.&amp;nbsp;멘토님들과의&amp;nbsp;소통을&amp;nbsp;통해&amp;nbsp;업계의&amp;nbsp;실제&amp;nbsp;사례와&amp;nbsp;다중&amp;nbsp;사용자&amp;nbsp;기반&amp;nbsp;네트워크&amp;nbsp;콘텐츠&amp;nbsp;제작&amp;nbsp;경험을&amp;nbsp;배우고,&amp;nbsp;언리얼&amp;nbsp;리슨,&amp;nbsp;데디케이티드&amp;nbsp;서버의&amp;nbsp;동작&amp;nbsp;구조,&amp;nbsp;Property와&amp;nbsp;RPC&amp;nbsp;통신을&amp;nbsp;이용한&amp;nbsp;네트워크&amp;nbsp;동기화&amp;nbsp;처리&amp;nbsp;방법도&amp;nbsp;체계적으로&amp;nbsp;익히고&amp;nbsp;싶습니다.&amp;nbsp;이를&amp;nbsp;통해&amp;nbsp;개발하는&amp;nbsp;게임이&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;사용자들에게&amp;nbsp;즐거움을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;기여하며,&amp;nbsp;더&amp;nbsp;나은&amp;nbsp;사용자&amp;nbsp;경험을&amp;nbsp;제공하고&amp;nbsp;싶습니다.&amp;nbsp;또한,&amp;nbsp;다른&amp;nbsp;개발자들과의&amp;nbsp;협업을&amp;nbsp;통해&amp;nbsp;프로젝트를&amp;nbsp;성공적으로&amp;nbsp;이끄는&amp;nbsp;데&amp;nbsp;필요한&amp;nbsp;소프트&amp;nbsp;스킬도&amp;nbsp;함께&amp;nbsp;함양하고&amp;nbsp;싶습니다.&lt;/p&gt;</description>
      <category>1기</category>
      <category>게임</category>
      <category>게임 클라이언트</category>
      <category>원티드</category>
      <category>포텐업</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/125</guid>
      <comments>https://deulee.tistory.com/125#entry125comment</comments>
      <pubDate>Wed, 9 Oct 2024 22:52:19 +0900</pubDate>
    </item>
    <item>
      <title>[C++11 - library features] std::begin/end</title>
      <link>https://deulee.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`std::begin`&lt;/b&gt;과 &lt;b&gt;`std::end`&lt;/b&gt;는 C++11에서 도입된 컨테이너의 일반적인 &lt;b&gt;`begin`&lt;/b&gt;과 &lt;b&gt;`end`&lt;/b&gt; 반복자를 반환해주는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이들의 특징은 특정 클래스의 멤버 함수로써 존재하는 것이 아니라 &lt;b&gt;&quot;raw array&quot;&lt;/b&gt;와 같이 `begin`과 `end` 멤버 함수가 없는 배열에도 유용하게 사용된다는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1693207767095&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

template &amp;lt;typename T&amp;gt;
int CountTwos(const T&amp;amp; container)
{
	return std::count_if(std::begin(container), std::end(container), [](int item){
		return item == 2;
	});
}

int main(void)
{
	std::vector&amp;lt;int&amp;gt; vec = {2, 2, 43, 435, 4345345, 3434};
	int arr[8] = {2, 12, 13 ,15 , 1, 66, 3, 9};
	auto a = CountTwos(vec); // 2
	auto b = CountTwos(arr); // 1
	std::cout &amp;lt;&amp;lt; a &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; b &amp;lt;&amp;lt; std::endl;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/123</guid>
      <comments>https://deulee.tistory.com/123#entry123comment</comments>
      <pubDate>Mon, 28 Aug 2023 16:30:43 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Move Semantics</title>
      <link>https://deulee.tistory.com/122</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Move Semantics(이동 의미론)&quot;은 C++11로부터 도입된 핵심적인 개념으로, 객체의 &lt;b&gt;&quot;소유권&quot;&lt;/b&gt;을 전환하거나 &lt;b&gt;&quot;전달&quot;&lt;/b&gt;하는 방식을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 C++에서 더 효율적인 객체 복사와 동적 자원 관리를 가능하게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Move Semantics&quot;를 이용하면 &lt;b&gt;임시 객체&lt;/b&gt;나 &lt;b&gt;rvalue&lt;/b&gt;로부터 객체의 리소스를 효율적으로 이동시켜 새로운 객체를 생성하거나 기존 객체에 리소스를 할당할 수 있다. 이를 통해 복사 대신 리소스의 &lt;b&gt;소유권을 이전&lt;/b&gt;함으로써 성능을 최적화시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, 동적 메모리 할당과 같이 무거운 작업에서 효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 주로 어디에서 사용할까?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체의 수명이 다할때&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;객체가 일시적으로 사용될 때&lt;br /&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`std::move`&lt;/b&gt;로 인해 명시적으로 호출될 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 이 세 가지 상황에서 사용되는데 다음의 예시를 들도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`std::vector`&lt;/b&gt;의 경우 &quot;이동&quot;을 하게 되면 단순히 몇개의 포인터를 복사하고 내부의 상태를 새로운 벡터에 넘기게 될 것이다. 하지만 &quot;복사&quot;를 하게 된다면 벡터의 포함되어 있는 모든 요소를 일일이 복사하게 될 것이다. 어차피 기존의 객체는 곧 파괴될텐데 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 복사가 불가능한 타입 (`std::unique_ptr`)과 같은 타입도 이동이 가능하게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 코드로 이용한 내용은 다음 글을 참고하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://deulee.tistory.com/121&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://deulee.tistory.com/121&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693206743865&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[C++11] Rvalue references&quot; data-og-description=&quot;&amp;quot;Rvalue reference&amp;quot;는 C++11에서 도입된 기능으로 오로지 Rvalue에만 할당될 수 있는 새로운 레퍼런스이다. 이를 선언하는 방법은 다음과 같다. T&amp;amp;&amp;amp; // where T is non-template type parameter (such as int, or a user-defined&quot; data-og-host=&quot;deulee.tistory.com&quot; data-og-source-url=&quot;https://deulee.tistory.com/121&quot; data-og-url=&quot;https://deulee.tistory.com/121&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bK0tKN/hyTL92lD25/CkdHhPCDz0SegGF8pHXiT1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cgEEab/hyTL29YGcO/wzhsbexqJN3wRr34574oU1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://deulee.tistory.com/121&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://deulee.tistory.com/121&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bK0tKN/hyTL92lD25/CkdHhPCDz0SegGF8pHXiT1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cgEEab/hyTL29YGcO/wzhsbexqJN3wRr34574oU1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[C++11] Rvalue references&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&quot;Rvalue reference&quot;는 C++11에서 도입된 기능으로 오로지 Rvalue에만 할당될 수 있는 새로운 레퍼런스이다. 이를 선언하는 방법은 다음과 같다. T&amp;amp;&amp;amp; // where T is non-template type parameter (such as int, or a user-defined&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;deulee.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://deulee.tistory.com/101&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://deulee.tistory.com/101&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693206799366&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[C++11] Special member functions for move semantics&quot; data-og-description=&quot;복사 생성자와 복사 대입 연산자는 복사본이 만들어질 때 호출됐었다. 하지만 C++11의 &amp;#96;move semantics&amp;#96;가 생기면서 &amp;#96;move constructor&amp;#96;와 &amp;#96;move assignment operator&amp;#96;를 만들 수 있게 되었다. #include class B { public: st&quot; data-og-host=&quot;deulee.tistory.com&quot; data-og-source-url=&quot;https://deulee.tistory.com/101&quot; data-og-url=&quot;https://deulee.tistory.com/101&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fNpVP/hyTIG8z0cv/kaSVXB8qLtrDUJH4Dopb70/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/QLYWc/hyTIEJHlJe/qkHzn9ZI5kIoVYZfXzTox1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://deulee.tistory.com/101&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://deulee.tistory.com/101&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fNpVP/hyTIG8z0cv/kaSVXB8qLtrDUJH4Dopb70/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/QLYWc/hyTIEJHlJe/qkHzn9ZI5kIoVYZfXzTox1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[C++11] Special member functions for move semantics&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;복사 생성자와 복사 대입 연산자는 복사본이 만들어질 때 호출됐었다. 하지만 C++11의 `move semantics`가 생기면서 `move constructor`와 `move assignment operator`를 만들 수 있게 되었다. #include class B { public: st&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;deulee.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>C++11</category>
      <category>move semantic</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/122</guid>
      <comments>https://deulee.tistory.com/122#entry122comment</comments>
      <pubDate>Mon, 28 Aug 2023 16:13:44 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Rvalue references</title>
      <link>https://deulee.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Rvalue reference&quot;는 C++11에서 도입된 기능으로 오로지 Rvalue에만 할당될 수 있는 새로운 레퍼런스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 선언하는 방법은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1693204110769&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;T&amp;amp;&amp;amp; // where T is non-template type parameter (such as int, or a user-defined type)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 &quot;Rvalue reference&quot;가 어떻게 바인딩되는지 확인해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1693204322512&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

int main(void)
{
	int x = 0; // `x` is an lvalue of type `int`
	int&amp;amp; xl = x; // `x1` is an lvalue of type `int&amp;amp;`
	int&amp;amp;&amp;amp; xr = x; // error -- `x` is an lvalue
	int&amp;amp;&amp;amp; xr2 = 0; // `xr2` is an lvalue of type `int&amp;amp;&amp;amp;` -- binds to the rvalue temporary, `0`

	void f(int&amp;amp; x) {}
	void f(int&amp;amp;&amp;amp; x) {}

	f(x); // calls f(int&amp;amp;)
	f(xl); // calls f(int&amp;amp;)
	f(3); // calls f(int&amp;amp;&amp;amp;)
	f(std::move(x)); // calls f(int&amp;amp;&amp;amp;)

	f(xr2); // calls f(int&amp;amp;)
	f(std::move(xr2)); // calls f(int&amp;amp;&amp;amp;)
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Rvalue Reference&quot;는 위와 같은 규칙을 가지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 다음과 같은 의문점이 생길 수 있다. 왜 `f(xr2)`는 `f(int&amp;amp;)` 함수를 호출하는 것일까? 분명한 것은 `xr2`의 타입이 `int&amp;amp;&amp;amp;`로 선언되었는데 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Rvalue와 Lvalue의 차이점을 알 필요가 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Rvalue vs Lvalue&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rvalue와 Lvalue는 이름에서도 나오듯이 차이점이 뚜렷한 &quot;값 카테고리&quot;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 어떤 부분에서 차이가 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Lvalue&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;lvalue는 &lt;b&gt;&quot;메모리에서 위치를 가지는 변수나 객체&quot;&lt;/b&gt;를 나타냄.&lt;/li&gt;
&lt;li&gt;변수의 이름이나 객체의 이름은 lvalue이다.&lt;/li&gt;
&lt;li&gt;lvalue는 주소를 가지며, 해당 주소를 통해 값을 변경하거나 접근할 수 있다.&lt;/li&gt;
&lt;li&gt;ex) 변수 &lt;b&gt;`x`&lt;/b&gt;, 배열 요소 &lt;b&gt;`arr[3]`&lt;/b&gt;, 클래스 객체 &lt;b&gt;`obj`&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Rvalue&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;rvalue는 &lt;b&gt;&quot;메모리에서 위치를 가지지 않는 일시적인 값&quot;&lt;/b&gt;을 나타냄.&lt;/li&gt;
&lt;li&gt;임시적인 값을 나타내거나, 표현식의 결과 값이나 상수 등이 rvalue이다.&lt;/li&gt;
&lt;li&gt;rvalue는 주소를 가지지 않으며, 일반적으로 임시적으로 생성되는 값이다.&lt;/li&gt;
&lt;li&gt;ex: 리터럴 상수 &lt;b&gt;`42`&lt;/b&gt;, 표현식 &lt;b&gt;`x + y`&lt;/b&gt;, 함수 호출 결과 &lt;b&gt;`getNumber()`&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이제 위의 예제에서 &lt;b&gt;`int&amp;amp;&amp;amp; z = 0`&lt;/b&gt;에서 &lt;b&gt;`f(z)`&lt;/b&gt;를 호출할 때 &lt;b&gt;`f(int&amp;amp;)`&lt;/b&gt;가 호출되는지 설명하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 설명했듯이, rvalue는 임시적인 값(메모리에서 위치를 가지지 않는 값)을 의미했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;b&gt;`main`&lt;/b&gt; 함수의 scope에서는 &quot;rvalue&quot;의 타입으로 선언된 변수 &lt;b&gt;`z`&lt;/b&gt;는 더 이상 임시적인 값이 아니다. 즉, 메모리에서 위치를 가지고 있는 것이다. 이 말은 변수 &lt;b&gt;`z`&lt;/b&gt;는 &quot;rvalue&quot;의 타입으로 초기화되었지만 &quot;lvalue&quot;의 속성을 가지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 &lt;b&gt;`f(int&amp;amp;)`&lt;/b&gt;가 호출되는 것이다.&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>C++</category>
      <category>Rvalue references</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/121</guid>
      <comments>https://deulee.tistory.com/121#entry121comment</comments>
      <pubDate>Mon, 28 Aug 2023 15:54:33 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Forwarding References(Universal References)</title>
      <link>https://deulee.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;Forwarding References&quot;&lt;/b&gt; 혹은 &lt;b&gt;&quot;Universal&lt;/b&gt; &lt;b&gt;References&quot;&lt;/b&gt;은 C++11에서 도입된 기능으로, 주로 함수 템플릿의 매개변수로 사용되는 형태를 가리키는 용어다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 템플릿으로 전달된 인자를 &lt;b&gt;&quot;원본의 값 카테고리와 레퍼런스 유형을 유지하면서 다른 함수로 전달하는 메커니즘&quot;&lt;/b&gt;을 일컷는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C++에는 Lvalue와 Rvalue이라는 값 카테고리가 있는데 주요 특징은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Lvalue&lt;/b&gt; : 주소를 가질 수 있는 변수나 객체를 의미함. (변수, 포인터)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Rvalue&lt;/b&gt; : 주소를 가질 수 없는 일시적인 값. (정수 리터럴)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 &quot;Forwarding References&quot;는 이러한 값 카테고리를 유지하면서 인자를 전달하는데 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Forwarding Reference의 생성 방법은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1693203157164&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;T&amp;amp;&amp;amp; // Where `T` is a template type parameter
auto&amp;amp;&amp;amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;Fowarding References&quot;&lt;/b&gt;이 가진 또 다른 특징은, &lt;b&gt;&quot;인자로 전달된 값의 카테고리에 따라 바인딩&quot;&lt;/b&gt;이 된다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 다음의 규칙이 성사되는데,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;`T&amp;amp; &amp;amp;`&lt;/b&gt; == &lt;b&gt;`T&amp;amp;`&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`T&amp;amp; &amp;amp;&amp;amp;`&lt;/b&gt; == &lt;b&gt;`T&amp;amp;`&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`T&amp;amp;&amp;amp; &amp;amp;`&lt;/b&gt; == &lt;b&gt;`T&amp;amp;`&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`T&amp;amp;&amp;amp; &amp;amp;&amp;amp;`&lt;/b&gt; == &lt;b&gt;`T&amp;amp;&amp;amp;`&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이것이 어떻게 활용되는지 예시를 보도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1693203662519&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

// Since C++14 or later:
void f(auto&amp;amp;&amp;amp; t) {
	//...
}

template &amp;lt;typename T&amp;gt;
void f(T&amp;amp;&amp;amp; t)
{
	// ...
}

int x = 0;
f(0); // `T` is `int`, deduces as `f(int &amp;amp;&amp;amp;)` =&amp;gt; `f(int&amp;amp;&amp;amp;)`
f(x); // `T` is `int&amp;amp;`, deduces as `f(int&amp;amp; &amp;amp;&amp;amp;)` =&amp;gt; `f(int&amp;amp;)`

int&amp;amp; y = 0;
f(y); // `T` is `int&amp;amp;`, deduces as `f(int&amp;amp; &amp;amp;&amp;amp;)` =&amp;gt; `f(int&amp;amp;)`

int&amp;amp;&amp;amp; z = 0; // `z` is an lvalue with type `int&amp;amp;&amp;amp;`
f(z); // `T` is `int&amp;amp;`, deduces as `f(int&amp;amp; &amp;amp;&amp;amp;)` =&amp;gt; `f(int&amp;amp;)`
f(std::move(z)); // `T` is `int`, deduces as `f(int &amp;amp;&amp;amp;)` =&amp;gt; `f(int&amp;amp;&amp;amp;)`
return 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시가 어떤 상황에서 어떻게 타입이 추론되는지 상세하게 나타내고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇듯 &quot;Forwarding references&quot;는 주로 함수 템플릿에 사용되며 전달하는 인자의 본래의 값 카테고리를 유지시켜주는 데 중요한 역할을 한다.&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>C++11</category>
      <category>Forwarding References</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/120</guid>
      <comments>https://deulee.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 28 Aug 2023 15:26:32 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Variadic templates</title>
      <link>https://deulee.tistory.com/119</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`...`&lt;/b&gt; 구문은 가변 인자를 받을 수 있게 된다. 가변 템플릿은 템플릿의 매개 변수로 여러 개의 인자를 받을 수 있도록 하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 함수나 클래스 템플릿을 정의할 때, 인자의 개수가 동적으로 변할 수 있을 때 유용하게 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, 인자의 갯수는 0개 이상을 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 최소 한개 이상의 가변 인자를 받는 템플릿을 &lt;b&gt;&quot;가변 템플릿&quot;&lt;/b&gt;이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693199422710&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

template &amp;lt;typename... T&amp;gt;
struct Arity {
	constexpr static int value = sizeof...(T);
};

int main(void)
{
	static_assert(Arity&amp;lt;&amp;gt;::value == 0, &quot;&quot;); // OK
	static_assert(Arity&amp;lt;int, char, short&amp;gt;::value == 3, &quot;&quot;); // OK
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시를 보면 템플릿의 매개 변수를 아예 받지 않거나 여러 개를 받았을 때의 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 예시는 가변 템플릿을 사용하는 예시를 보도록 하겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1693199876180&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;template&amp;lt;typename T&amp;gt;
void Print(const T&amp;amp; value)
{
	std::cout &amp;lt;&amp;lt; value &amp;lt;&amp;lt; &quot; &quot;;
}

template &amp;lt;typename T, typename... Args&amp;gt;
void Print(const T&amp;amp; value, const Args&amp;amp;... args)
{
	std::cout &amp;lt;&amp;lt; value &amp;lt;&amp;lt; &quot; &quot;;
	Print(args...);
}

int main(void)
{
	Print(&quot;hello&quot;, 1, 2.7, 'a');
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 타입의 인자를 받아들이는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 &lt;b&gt;`Print`&lt;/b&gt; 함수가 재귀를 돌면서 각각의 인자를 차례대로 호출하는 것을 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693202139752&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;template &amp;lt;typename First, typename... Args&amp;gt;
auto sum(const First first, const Args... args) -&amp;gt; decltype(first)
{
	const auto values = {first, args...};
	return std::accumulate(values.begin(), values.end(), First{0});
}

int main(void)
{
	std::cout &amp;lt;&amp;lt; sum(1, 2, 3) &amp;lt;&amp;lt; std::endl;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시는 가변 인자를 이용해 &quot;initializer list&quot;를 만들고 이를 통해 가변 인자의 요소를 가리킬 수 있게 되었다.&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>C++11</category>
      <category>Variadic templates</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/119</guid>
      <comments>https://deulee.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 28 Aug 2023 14:57:07 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Initializer lists</title>
      <link>https://deulee.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Initializer lists&quot;는 C++11에서 도입된 객체를 초기화하는 데 사용되는 편리한 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 &quot;braced list(중괄호)&quot;를 이용하여 만들 수 있는데 예를 들어 `{1, 2, 3}`은 정수의 배열을 만든다. 그리고 이 타입은 &lt;b&gt;`std::initializer_list&amp;lt;int&amp;gt;`&lt;/b&gt;가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 함수에 인자로 넘길 때 벡터 대신 사용하기 유용하다.&lt;/p&gt;
&lt;pre id=&quot;code_1693198551044&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

int sum(const std::initializer_list&amp;lt;int&amp;gt;&amp;amp; list)
{
	int total = 0;
	for (auto&amp;amp; it : list)
		total += it;
	return total;
}

int main(void)
{
	auto list = {1, 2, 3}; // `std::initializer_list&amp;lt;int&amp;gt;`
	sum(list); // 6
	sum({1, 2, 3}); // 6;
	sum({}); // 0;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>C++11</category>
      <category>initializer lists</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/118</guid>
      <comments>https://deulee.tistory.com/118#entry118comment</comments>
      <pubDate>Mon, 28 Aug 2023 13:56:15 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Static Assertions</title>
      <link>https://deulee.tistory.com/117</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`static_assert`는&lt;/b&gt; C++11부터 제공되는 기능으로 컴파일 시간에 조건을 검사하여 컴파일 타임 에러를 발생시키는 역할을 수행하는 키워드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 컴파일 시간에 논리적인 조건을 확인하거나 특정한 제약을 검사하여 코드의 안전성을 높일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`static_assert`의 기본 구조는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1693041928505&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static_assert(condition, message);&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;`condition`:&lt;/b&gt; 검사하고 싶은 조건을 나타내는 표현식. 만약 이 조건이 `false`로 판단되면 컴파일 에러 발생&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`message`:&lt;/b&gt; 컴파일 에러 메시지를 지정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre id=&quot;code_1693042252725&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;type_traits&amp;gt;

template &amp;lt;typename T&amp;gt;
void print_Int() {
	static_assert(std::is_integral&amp;lt;T&amp;gt;::value, &quot;T must be integral type&quot;);
	std::cout &amp;lt;&amp;lt; &quot;Size of &quot; &amp;lt;&amp;lt; typeid(T).name() &amp;lt;&amp;lt; &quot;: &quot; &amp;lt;&amp;lt; sizeof(T) &amp;lt;&amp;lt; &quot; bytes&quot; &amp;lt;&amp;lt; std::endl;
}

int main(void)
{
	print_Int&amp;lt;int&amp;gt;();
	// print_Int&amp;lt;double&amp;gt;(); // error
	// print_size&amp;lt;std::string&amp;gt;(); // error: T must be an integral type
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서 `print_Int` 함수는 템플릿으로 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`static_assert`를 사용하여 템플릿의 매개변수 `T`가 정수형 타입일 때만 컴파일을 허용하도록 제한하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 함으로써 아래의 `double`와 `std::string`에서 에러를 발생시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`static_assert`&lt;/b&gt;는 코드의 안전성을 높이는데 도움을 주고, 특히 템플릿 메타 프로그래밍이나 일반 코드에서 조건을 검사하여 예기치 않은 문제를 방지하는데 사용된다.&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>C++11</category>
      <category>static_assert</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/117</guid>
      <comments>https://deulee.tistory.com/117#entry117comment</comments>
      <pubDate>Sat, 26 Aug 2023 18:32:54 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] auto</title>
      <link>https://deulee.tistory.com/116</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`auto`&lt;/b&gt; 키워드는 C++11부터 도입된 기능으로, &lt;b&gt;변수의 타입을 &quot;컴파일러&quot;가 초기화식을 기반으로 자동으로 추론&lt;/b&gt;하도록 하는 기능을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 먼저 보도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1693039683075&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

int main(void)
{
	auto a = 3.14; // double
	auto b = 1; // int
	auto&amp;amp; c = b; // int&amp;amp;
	auto d = {0}; // std::initializer_list&amp;lt;int&amp;gt;
	auto&amp;amp;&amp;amp; e = 1; // int&amp;amp;&amp;amp;
	auto&amp;amp;&amp;amp; f = b; // int&amp;amp;
	auto g = new auto(123); // int*
	const auto h = 1; // const int
	auto i = 1, j = 2, k = 3; // int, int, int
	auto l = 1, m = true, n = 1.61; // error -- `l` deduced to be int, `m` is bool
	auto o; // error -- `o` requires initializer
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 위를 보면 궁금한 점이 몇몇 있지만 이는 나중에 다루도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쨋든, 예시를 보면 초기화 타입에 맞게 알맞게 타입이 추론되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이는 가독성을 굉장히 높여주는데 다음의 코드도 보도록 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1693039786875&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;std::vector&amp;lt;int&amp;gt; v = ...;
std::vector&amp;lt;int&amp;gt;::const_iterator cit = v.cbegin();
// vs
auto cit = v.cbegin();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예제와 같이 코드의 길이를 대폭 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;함수&quot;&lt;/b&gt;에서도 &lt;b&gt;`auto`&lt;/b&gt; 키워드를 사용하여 리턴 타입을 추론할 수 있다. 하지만 물론 C++11에서는 리턴 타입을 명시적으로 지정해야 하기 때문에 &lt;b&gt;`decltype`&lt;/b&gt; 키워드를 사용하여 이를 해결할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693040092683&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;template &amp;lt;typename X, typename Y&amp;gt;
auto add(X x, Y y) -&amp;gt; decltype(x + y)
{
	return x + y;
}

add(1, 2); // == 3
add(1, 2.0); // == 3.0
add(1.5, 1.5); // == 3.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예제에서는 이전에 배운 &lt;b&gt;&quot;trailing return type&quot;&lt;/b&gt;과 &lt;b&gt;`decltype`&lt;/b&gt;을 이용하여 예시를 작성해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`auto`&lt;/b&gt;의 타입은 &lt;b&gt;`decltype`&lt;/b&gt;에 의해 추론된 타입으로 결정되게 된다. 즉, &lt;b&gt;`(x&lt;/b&gt;&amp;nbsp;&lt;b&gt;+&lt;/b&gt; &lt;b&gt;y)`&lt;/b&gt; 표현식에 의해 추론된다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;auto의 작동 원리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`auto`의&lt;/b&gt; 타입 추론은 대체로 템플릿 타입 추론과 같지만, &lt;b&gt;`auto`&lt;/b&gt; 타입 추론은 &lt;b&gt;`{중괄호 초기화}`&lt;/b&gt;가 &lt;b&gt;`std::initializer_list`&lt;/b&gt;를 나타낸다고 가정하는 반면 템플릿 타입 추론은 그렇지 않다는 차이가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`auto`&lt;/b&gt; 키워드는 총 3개의 경우를 통해서 타입을 추론하는데 다음과 같다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;경우 1:&lt;/b&gt; &lt;span style=&quot;color: #666666;&quot;&gt;타입 지정자가 포인터나 참조 타입이지만 보편 참조(universal reference)는 아닌 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경우 2:&lt;/b&gt; &lt;span style=&quot;color: #666666;&quot;&gt;타입 지정자가 보편 참조(universal reference)인 경우.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;경우 3:&lt;/b&gt; &lt;span style=&quot;color: #666666;&quot;&gt;타입 지정자가 포인터도 아니고 참조도 아닌 경우.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1693041058960&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

// 경우 1 : 타입 지정자가 포인터나 참조 타입이지만 보편 참조(universal reference)가 아닌경우
// 경우 2 : 타입 지정자가 보편 참조(universal reference)인 경우
// 경우 3 : 타입 지정자가 포인터도 아니고 참조도 아닌 경우.

int main(void)
{
	// `int`
	auto x = 13; // 경우 3 -- x는 포인터도 아니고 참조도 아님

	// `const int`
	const auto cx = x; // 경우 3 -- cx는 포인터도 아니고 참조도 아님	

	// `const int&amp;amp;`
	const auto&amp;amp; rx = x; // 경우 1 -- rx는 보편 참조(universal reference)가 아닌 참조

	// `int&amp;amp;`
	auto&amp;amp;&amp;amp; uref1 = x; // x는 `int`이자 lvalue이므로 uref1의 타입은 `int&amp;amp;`

	// `const int&amp;amp;`
	auto&amp;amp;&amp;amp; uref2 = cx; // cx는 `const int`이자 lvalue이므로 uref2의 타입은 `const int&amp;amp;`

	// `int&amp;amp;&amp;amp;`
	auto&amp;amp;&amp;amp; uref3 = 27; // 27은 `int`이자 rvalue이므로 uref3의 타입은 `int&amp;amp;&amp;amp;`
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로써 맨 처음에 생긴 의문이 어느정도는 해결되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 타입 추론에 관련해서는 나중에 &quot;Modern Effective C++&quot;이라는 책을 통해 더 자세하게 작성하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 `auto`라는 키워드가 있고 어떻게 사용하는지 아는 것에 만족하자.&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <category>auto</category>
      <category>C++</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/116</guid>
      <comments>https://deulee.tistory.com/116#entry116comment</comments>
      <pubDate>Sat, 26 Aug 2023 18:12:09 +0900</pubDate>
    </item>
    <item>
      <title>[C++11] Lamda Expressions</title>
      <link>https://deulee.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;`lamda`&lt;/b&gt;는 C+11부터 도입된 기능으로, 이름 없는 함수 객체로 지역내에 있는 변수들을 캡처하는 기능이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 `lamda`의 구조는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1693038242907&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[capture](parameters) -&amp;gt; return_type {
	// 함수 몸체
} (call lamda); // 생략 가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 요소는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;`capture`&lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;는 외부 변수를 람다 내부에서 사용할 때 그 값을 어떻게 캡처할 것인지를 지정함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`parameters`&lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;는 람다 함수의 매개변수를 정의함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`return_type`&lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;은 람다 함수의 반환 타입을 지정함. (생략 가능)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`함수 몸체`&lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;는 실제 함수의 내용을 작성하는 부분&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`호출 인자`&lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;는 함수 호출 시 인자를 의미함. (생략 가능)&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캡처를 할 때 다양한 특징이 있는데 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;`[]`&lt;/b&gt; - 아무것도 캡처하지 않음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`[=]`&lt;/b&gt; - 지역내의 모든 객체 (지역 변수, 매개 변수)의 값을 복사함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`[&amp;amp;]`&lt;/b&gt; - 지역내의 모든 객체 (지역 변수, 매개 변수)의 값을 참조함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`[this]`&lt;/b&gt; - `this`를 참조함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;`[a, &amp;amp;b]`&lt;/b&gt; - `a`의 값을 복사하고 `b`를 참조함.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1693038661826&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

int main(void)
{
	int x = 1;

	auto getX = [=] { return x; };
	std::cout &amp;lt;&amp;lt; getX() &amp;lt;&amp;lt; std::endl; // == 1

	auto addX = [=](int y) { return x + y; };
	std::cout &amp;lt;&amp;lt; addX(3) &amp;lt;&amp;lt; std::endl; // == 4;

	auto getXRef = [&amp;amp;]() -&amp;gt; int&amp;amp; { return x; };
	int&amp;amp; y = getXRef();
	y = 6;
	std::cout &amp;lt;&amp;lt; x &amp;lt;&amp;lt; std::endl; // 6;
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다는 또한 &lt;b&gt;함수의 인자로서 넣어질 수 있다&lt;/b&gt;. 마치 함수 포인터처럼 말이다.&lt;/p&gt;
&lt;pre id=&quot;code_1693039339476&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;std::vector&amp;lt;int&amp;gt; varr{0, 4, 6, 1, 3, 4};
std::sort(varr.begin(), varr.end(), [](int x, int y){return x &amp;lt; y;});
for (auto&amp;amp; it : varr)
	std::cout &amp;lt;&amp;lt; it &amp;lt;&amp;lt; ' '; // 0 1 3 4 4 6
std::cout &amp;lt;&amp;lt; std::endl;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주의할 점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 디폴트로, &quot;value-captures&quot; 즉, &lt;b&gt;값으로 캡처 된 것은 남다 내부에서 변경하는 것이 금지 되어있다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는, 컴파일러 생성 메서드는 &lt;b&gt;`const`&lt;/b&gt;로 표시되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &quot;parameter-list&quot; 이후에 &lt;b&gt;`mutable`&lt;/b&gt; 키워드를 지정하게 될 시 &quot;value-captured&quot; 값을 바꿀 수 있게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1693039044359&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;auto f1 = [&amp;amp;x] { x = 2; }; // OK: x is a reference and modifies the original
auto f2 = [x] { x = 2; }; // error -- the lamda can only perform const-operations on the captured value
auto f3 = [x]() mutable { x = 6; }; // OK: the lamda can perform any operations on the captured value&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>C++/Modern C++(11, 14, 17, 20)</category>
      <author>deulee</author>
      <guid isPermaLink="true">https://deulee.tistory.com/115</guid>
      <comments>https://deulee.tistory.com/115#entry115comment</comments>
      <pubDate>Sat, 26 Aug 2023 17:42:45 +0900</pubDate>
    </item>
  </channel>
</rss>