[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기

Chris Ohk
Chris OhkEngine Engineer um Momenti, Inc
옥찬호 / 넥슨 (NEXON KOREA), Visual C++ MVP
녹슨 C++ 코드에 모던 C++로 기름칠하기
시작하기 전에…
• 모던 C++이란 C++11/14를 말합니다.
• C++11/14을 통한 개선 뿐만 아니라
기존 C++을 통한 개선 방법도 함께 포함합니다.
• 모던 C++을 모르는 분들을 위해 최대한 쉽게 설명합니다.
• 예제 코드가 많은 부분을 차지합니다.
녹슨 C++ 코드란?
int _output(
FILE* stream,
char const* format,
va_list arguments
)
{
// ...
}
#ifdef _UNICODE
int _woutput (
#else /* _UNICODE */
int _output (
#endif /* _UNICODE */
FILE* stream,
_TCHAR const* format,
va_list arguments
)
{
// ...
}
#ifdef _UNICODE
#ifdef POSITIONAL_PARAMETERS
int _woutput_p (
#else /* POSITIONAL_PARAMETERS */
int _woutput (
#endif /* POSITIONAL_PARAMETERS */
#else /* _UNICODE */
#ifdef POSITIONAL_PARAMETERS
int _output_p (
#else /* POSITIONAL_PARAMETERS */
int _output (
#endif /* POSITIONAL_PARAMETERS */
#endif /* _UNICODE */
FILE* stream,
_TCHAR const* format,
va_list arguments
)
{ ... }
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pfd));
if (SUCCEEDED(hr)) {
IFileDialogEvents *pfde = NULL;
hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
if (SUCCEEDED(hr)) {
DWORD dwCookie;
hr = pfd->Advise(pfde, &dwCookie);
if (SUCCEEDED(hr)) {
DWORD dwFlags;
hr = pfd->GetOptions(&dwFlags);
if (SUCCEEDED(hr)) {
hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
if (SUCCEEDED(hr)) {
hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
if (SUCCEEDED(hr)) {
hr = pfd->SetFileTypeIndex(INDEX_WORDDOC);
if (SUCCEEDED(hr)) {
hr = pfd->SetDefaultExtension(L"doc;docx");
if (SUCCEEDED(hr)) {
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
고치고 싶다… 하지만
• 이미 고치기엔 길어져버린 코드
• 어디서부터 손을 써야 할 지 모름
• 코드는 점점 산으로…
• 아 귀찮다… ㅁㄴㅇㄹ
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
어디에 기름칠을 해볼까?
• 전처리기
• 리소스 관리
• 함수
• 타입, 반복문
• 기타 등등…
전처리기
조건부 컴파일
• #if, #ifdef, #ifndef, #elif, #else, …
• 많이 쓸수록 복잡해진다.
• 많이 쓸수록 이해하기 어렵다.
• 많이 쓸수록 유지보수하기 어렵다.
#ifdef _UNICODE
int _woutput (
#else /* _UNICODE */
int _output (
#endif /* _UNICODE */
FILE* stream,
_TCHAR const* format,
va_list arguments
)
{
// ...
}
template <typename T>
static int common_output(
FILE* stream,
T const* format,
va_list arguments
)
{
// ...
}
int _output(FILE* stream, char const* format, va_list const arguments) {
return common_output(stream, format, arguments);
}
int _woutput(FILE* stream, wchar_t const* format, va_list const arguments) {
return common_output(stream, format, arguments);
}
// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
케이스 바이 케이스
• 타입에 따른 조건부 컴파일은 함수 템플릿을 통해 개선한다.
• 하지만 #ifdef를 사용해야 되는 경우도 있다.
• 32비트 vs 64비트 코드
• DEBUG 모드 vs Non-DEBUG 모드
• 컴파일러, 플랫폼, 언어에 따라 다른 코드
• 반드시 사용해야 된다면, 코드를 단순화하는 것이 좋다.
• 중첩 #ifdef를 피하고, 함수의 일부를 조건부 컴파일에 넣지 않도록 한다.
매크로
• #define …
• 변수 대신 사용하는 매크로 : #define RED 1
• 함수 대신 사용하는 매크로 : #define SQUARE(x) ((x) * (x))
• 수많은 문제를 일으키는 장본인
• 컴파일러가 타입에 대한 정보를 갖기 전에 계산됨
• 필요 이상으로 많이 사용
변수 대신 사용하는 매크로
#define red 0
#define orange 1
#define yellow 2
#define green 3
#define blue 4
#define purple 5
#define hot_pink 6
void f()
{
unsigned orange = 0xff9900;
}
warning C4091: '' : ignored on left of 'unsigned int' when no variable is declared
error C2143: syntax error : missing ';' before 'constant'
error C2106: '=' : left operand must be l-value
#define red 0
#define orange 1
#define yellow 2
#define green 3
#define blue 4
#define purple 5
#define hot_pink 6
void f()
{
unsigned 2 = 0xff00ff;
}
warning C4091: '' : ignored on left of 'unsigned int' when no variable is declared
error C2143: syntax error : missing ';' before 'constant'
error C2106: '=' : left operand must be l-value
#define RED 0
#define ORANGE 1
#define YELLOW 2
#define GREEN 3
#define BLUE 4
#define PURPLE 5
#define HOT_PINK 6
void g(int color); // valid values are 0 through 6
void f()
{
g(HOT_PINK); // Ok
g(9000); // Not ok, but compiler can’t tell
}
enum color_type
{
red = 0,
orange = 1,
yellow = 2,
green = 3,
blue = 4,
purple = 5,
hot_pink = 6
};
enum color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void g(color_type color);
void f()
{
g(hot_pink); // Ok
g(9000); // Not ok, compiler will report error
}
error C2664: 'void g(color_type)' : cannot convert argument 1 from 'int' to 'color_type'
enum color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void f()
{
int x = red; // Ugh
int x = red + orange; // Double ugh
}
enum color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
enum traffic_light_state
{
red, yellow, green
};
error C2365: 'red' : redefinition; previous definition was 'enumerator‘
error C2365: 'yellow' : redefinition; previous definition was 'enumerator‘
error C2365: 'green' : redefinition; previous definition was 'enumerator'
열거체의 문제점
• 묵시적인 int 변환
• 열거체의 타입을 명시하지 못함
• 이상한 범위 적용
→ 열거체 클래스(enum class)의 등장!
enum class color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void g(color_type color);
void f()
{
g(color_type::red);
}
enum class color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void g(color_type color);
void f()
{
int x = color_type::hot_pink;
}
error C2440: 'initializing' : cannot convert from 'color_type' to 'int'
enum class color_type
{
red, orange, yellow, green, blue, purple, hot_pink
};
void g(color_type color);
void f()
{
int x = static_cast<int>(color_type::hot_pink);
}
열거체 클래스를 사용하자
• 묵시적인 int 변환
→ 명시적인 int 변환
• 열거체의 타입을 명시하지 못함
→ 타입 명시 가능
• 이상한 범위 적용
→ 범위 지정 연산자를 통해 구분
함수 대신 사용하는 매크로
#define make_char_lowercase(c) 
((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
void make_string_lowercase(char* s)
{
while (make_char_lowercase(*s++))
;
}
#define make_char_lowercase(c) 
((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
void make_string_lowercase(char* s)
{
while (((*s++) = (((*s++) >= 'A') && ((*s++) <= 'Z'))
? ((*s++) - 'A' + 'a') : (*s++)))
;
}
// Old, ugly macro implementation:
#define make_char_lowercase(c) 
((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
// New, better function implementation:
inline char make_char_lowercase(char& c)
{
if (c > 'A' && c < 'Z')
{
c = c - 'A' + 'a';
}
return c;
}
열거체, 함수를 사용하자
• 변수 대신 사용하는 매크로에는 열거체를 사용하자.
• 열거체에서 발생할 수 있는 문제는 enum class로 해결할 수 있다.
• 열거체 대신 ‘static const’ 변수를 사용하는 방법도 있다.
• 함수 대신 사용하는 매크로에는 함수를 사용하자.
• 읽기 쉽고, 유지보수하기 쉽고, 디버깅하기 쉽다.
• 성능에 따른 오버헤드도 없다.
리소스 관리
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pfd));
if (SUCCEEDED(hr)) {
IFileDialogEvents *pfde = NULL;
hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
if (SUCCEEDED(hr)) {
DWORD dwCookie;
hr = pfd->Advise(pfde, &dwCookie);
if (SUCCEEDED(hr)) {
DWORD dwFlags;
hr = pfd->GetOptions(&dwFlags);
if (SUCCEEDED(hr)) {
hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
if (SUCCEEDED(hr)) {
hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes);
if (SUCCEEDED(hr)) {
hr = pfd->SetFileTypeIndex(INDEX_WORDDOC);
if (SUCCEEDED(hr)) {
hr = pfd->SetDefaultExtension(L"doc;docx");
if (SUCCEEDED(hr)) {
IFileDialog *pfd = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, IID_PPV_ARGS(&pfd));
if (FAILED(hr))
return hr;
IFileDialogEvents *pfde = NULL;
hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
if (FAILED(hr))
return hr;
DWORD dwCookie;
hr = pfd->Advise(pfde, &dwCookie);
if (FAILED(hr))
return hr;
DWORD dwFlags;
hr = pfd->GetOptions(&dwFlags);
if (FAILED(hr))
return hr;
}
psiResult->Release();
}
}
}
}
}
}
}
pfd->Unadvise(dwCookie);
}
pfde->Release();
}
pfd->Release();
}
return hr;
void ExampleWithoutRAII() {
std::FILE* file_handle = std::fopen("logfile.txt", "w+");
if (file_handle == nullptr)
throw std::runtime_error("File couldn't open!");
try {
if (std::fputs("Hello, Log File!", file_handle) == EOF)
throw std::runtime_error("File couldn't write!");
// continue writing to logfile.txt ... do not return
// prematurely, as cleanup happens at the end of this function
}
catch (...)
{
std::fclose(file_handle);
throw;
}
std::fclose(file_handle);
}
RAII
• 자원 획득은 초기화다 (Resource Acquisition Is Initialization)
• 객체의 생성에 맞춰 메모리와 시스템 리소스를 자동으로 할당
• 객체의 소멸에 맞춰 메모리와 시스템 리소스를 자동으로 해제
→ 생성자 안에서 리소스를 할당하고, 소멸자에서 리소스를 해제
void ExampleWithRAII()
{
// open file (acquire resource)
File logFile("logfile.txt");
logFile.Write("Hello, Log File!");
// continue writing to logfile.txt ...
}
File::File(const char* filename)
: m_file_handle(std::fopen(filename, "w+"))
{
if (m_file_handle == NULL)
throw openError();
}
File::~File()
{
std::fclose(m_file_handle);
}
void ExampleWithRAII()
{
// open file (acquire resource)
File* logFile = new File("logfile.txt");
logFile->Write("Hello, Log File!");
// continue writing to logfile.txt ...
}
File::File(const char* filename)
: m_file_handle(std::fopen(filename, "w+"))
{
if (m_file_handle == NULL)
throw openError();
}
File::~File()
{
std::fclose(m_file_handle);
}
다시 발생하는 문제
• 파일 입출력과 관련한 예외 처리를 간편하게 하기 위해
File 클래스를 만들어 생성자와 소멸자로 처리했다.
• 하지만, 정작 File 클래스를 동적으로 할당하는 경우
소멸자가 호출되지 않아 파일을 닫지 않는 문제가 발생한다.
• 좋은 방법이 없을까?
→ 스마트 포인터(Smart Pointer)의 등장!
스마트 포인터
• 좀 더 똑똑한 포인터
• 스마트 포인터를 사용하면 명시적으로 해제할 필요가 없다.
• 사용하는 이유
• 적은 버그, 자동 청소, 자동 초기화
• Dangling 포인터 발생 X, Exception 안전
• 효율성
void ExampleWithRAII()
{
// open file (acquire resource)
std::unique_ptr<File> logFile = std::make_unique<File>("logfile.txt");
logFile->Write("Hello, Log File!");
// continue writing to logfile.txt ...
}
File::File(const char* filename)
: m_file_handle(std::fopen(filename, "w+"))
{
if (m_file_handle == NULL)
throw openError();
}
File::~File()
{
std::fclose(m_file_handle);
}
스마트 포인터의 종류
• 경우에 따라 여러 종류의 스마트 포인터를 사용할 수 있다.
• shared_ptr : 객체의 소유권을 복사할 수 있는 포인터
(여러 shared_ptr 객체가 같은 포인터 객체를 가리킬 수 있음)
• unique_ptr : 객체의 소유권을 복사할 수 없는 포인터
(하나의 unique_ptr 객체만이 하나의 포인터 객체를 가리킬 수 있음)
std::unique_ptr
ptrA Song 개체
ptrA Song 개체
ptrB
auto ptrA = std::make_unique<Song>(L"Diana Krall", L"The Look of Love");
auto ptrB = std::move(ptrA);
std::unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title)
{
// Implicit move operation into the variable that stores the result.
return std::make_unique<Song>(artist, title);
}
void MakeSongs()
{
// Create a new unique_ptr with a new object.
auto song = std::make_unique<Song>(L"Mr. Children", L"Namonaki Uta");
// Use the unique_ptr.
std::vector<std::wstring> titles = { song->title };
// Move raw pointer from one unique_ptr to another.
std::unique_ptr<Song> song2 = std::move(song);
// Obtain unique_ptr from function that returns by value.
auto song3 = SongFactory(L"Michael Jackson", L"Beat It");
}
std::shared_ptr
MyClass
제어 블록 참조 개수 = 1
개체에 대한 포인터
제어 블록에 대한 포인터
p1
std::shared_ptr
MyClass
제어 블록 참조 개수 = 2
개체에 대한 포인터
제어 블록에 대한 포인터
p1
개체에 대한 포인터
제어 블록에 대한 포인터
p2
// Use make_shared function when possible.
auto sp1 = std::make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");
// Ok, but slightly less efficient.
// Note: Using new expression as constructor argument
// creates no named variable for other code to access.
std::shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance"));
// When initialization must be separate from declaration, e.g. class members,
// initialize with nullptr to make your programming intent explicit.
std::shared_ptr<Song> sp5(nullptr);
//Equivalent to: shared_ptr<Song> sp5;
//...
sp5 = std::make_shared<Song>(L"Elton John", L"I'm Still Standing");
리소스 관리는 스마트 포인터로
• RAII를 사용하자!
• 읽고, 쓰고, 유지보수하기 쉽다.
• 자원 관리에 대한 걱정을 할 필요가 없다.
• C++ 코드 품질을 향상시키는 가장 쉬운 방법!
• 기왕이면 스마트 포인터로!
• shared_ptr
• unique_ptr
함수
std::vector<int>::const_iterator iter = cardinal.begin();
std::vector<int>::const_iterator iter_end = cardinal.end();
int total_elements = 1;
while (iter != iter_end)
{
total_elements *= *iter;
++iter;
}
template <typename T>
struct product {
product(T& storage) : value(storage) {}
template<typename V>
void operator()(V& v)
{
value *= v;
}
T& value;
};
std::vector<int> cardinal;
int total_elements = 1;
for_each(cardinal.begin(), cardinal.end(),
product<int>(total_elements));
int total_elements = 1;
for_each(cardinal.begin(), cardinal.end(), [&total_elements](int i)
{
total_elements *= i;
});
struct mod
{
mod(int m) : modulus(m) {}
int operator()(int v)
{ return v % modulus; }
int modulus;
};
int my_mod = 8;
std::transform(in.begin(), in.end(),
out.begin(), mod(my_mod));
int my_mod = 8;
transform(in.begin(), in.end(), out.begin(),
[my_mod](int v) -> int
{ return v % my_mod; });
Functor Lambda Expression
람다식
[my_mod] (int v) -> int { return v % my_mod; }
개시자
(Introducer Capture)
인자
(Arguments)
반환 타입
(Return Type)
함수의 몸통
(Statement)
int x = 10, y = 20;
[] {}; // 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
1
2
2
void fa(int x, function<void(void)> f) { ++x; f(); }
void fb(int x, function<void(int)> f) { ++x; f(x); }
void fc(int &x, function<void(void)> f) { ++x; f(); }
int x = 1;
fa(x, [x] { cout << x << endl; });
fb(x, [](int x) { cout << x << endl; });
fc(x, [&x] { cout << x << endl; });
WNDCLASSEX wcex;
wcex.lpfnWndProc= [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ->
LRESULT {
switch (message) {
case WM_COMMAND:
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
char szText[256];
GetWindowTextA(hwnd, szText, 256);
cout << szText << endl;
return TRUE;
}, 0);
HANDLE hT = CreateThread(NULL, 0, [](LPVOID lpThreadParameter) -> DWORD {
for (int i = 0; i < 1000; i++) {
this_thread::sleep_for(milliseconds{ 10 });
cout << i << endl;
}
return 0;
}, NULL, 0, NULL);
람다식을 사용하자
• 짧고, 간결하고, while 문과 같은 행사 코드 없이
깔끔하게 작성할 수 있다.
• 수십줄의 코드를 1~2줄로 간추릴 수 있다.
• Functor, Callback Function을 대체해서 사용할 수 있다.
• 반복적으로 사용하는 함수가 아니라면 람다식을 사용하자!
간단하게 적용 가능한 기능들
auto 키워드
• 컴파일 타임에 타입을 추론해 어떤 타입인지 결정한다.
• 컴파일 타임에 추론이 불가능하다면, 오류가 발생한다.
std::vector<std::tuple<std::string, int, double>> vStudents;
for (std::vector<std::tuple<std::string, int, double>>::iterator iter =
vStudents.begin(); iter != vStudents.end(); ++iter) { … }
std::vector<std::tuple<std::string, int, double>> vStudents;
for (auto iter = vStudents.begin(); iter != vStudents.end(); ++iter) { … }
범위 기반 for문
int arr[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < 5; ++i)
std::cout << arr[i] << std::endl;
return 0;
}
int arr[] = { 1, 2, 3, 4, 5 };
for (auto& i : arr)
std::cout << i << std::endl;
return 0;
}
정리
// circle and shape are user-defined types
circle* p = new circle(42);
vector<shape*> v = load_shapes();
for (vector<circle*>::iterator i = v.begin(); i != v.end(); ++i) {
if (*i && **i == *p)
cout << **i << " is a matchn";
}
for (vector<circle*>::iterator i = v.begin(); i != v.end(); ++i) {
delete *i; // not exception safe
}
delete p;
정리
// circle and shape are user-defined types
auto p = make_shared<circle>(42);
vector<shared_ptr<shape>> v = load_shapes();
for_each(begin(v), end(v), [&](const shared_ptr<shape>& s) {
if (s && *s == *p)
cout << *s << " is a matchn";
});
정리
• 대체할 수 있는 조건부 컴파일은 템플릿으로 기름칠!
• 매크로는 가급적 사용하지 말고 열거체와 함수로 기름칠!
• 리소스 관리에는 RAII, 기왕이면 스마트 포인터로 기름칠!
• 일회성으로 사용하는 함수는 람다식으로 기름칠!
• 복잡한 타입에는 auto로 기름칠!
• 반복 횟수에 고통받지 말고 범위 기반 for문으로 기름칠!
정리
• 모던 C++을 통해 대체할 수 있는 코드는 많습니다!
(하지만 제한된 시간으로 인해 …)
• 다음 사이트에서 모던 C++ 예제 코드를 확인하실 수 있습니다.
http://www.github.com/utilForever/ModernCpp
• C++ 핵심 가이드라인
• 영문 : https://github.com/isocpp/CppCoreGuidelines
• 한글 : https://github.com/CppKorea/CppCoreGuidelines
Quiz
#include <iostream>
#include <memory>
#include <vector>
class C {
public:
void foo() { std::cout << "A"; }
void foo() const { std::cout << "B"; }
};
struct S {
std::vector<C> v;
std::unique_ptr<C> u;
C* const p;
S() : v(1), u(new C()), p(u.get()) {}
};
Quiz #1
int main() {
S s;
const S& r = s;
s.v[0].foo(); s.u->foo(); s.p->foo();
r.v[0].foo(); r.u->foo(); r.p->foo();
}
AAABAA
#include <iostream>
struct A {
A() { std::cout << "A"; }
A(const A& a) { std::cout << "B"; }
virtual void f() { std::cout << "C"; }
};
int main() {
A a[2];
for (auto x : a) {
x.f();
}
}
Quiz #2
AABCBC
#include <iostream>
struct A {
A() { std::cout << "A"; }
A(const A& a) { std::cout << "B"; }
virtual void f() { std::cout << "C"; }
};
int main() {
A a[2];
for (auto& x : a) {
x.f();
}
}
Quiz #3
AACC
C++ Korea
• http://www.facebook.com/groups/cppkorea
http://www.github.com/cppkorea
감사합니다.
• MSDN Forum http://aka.ms/msdnforum
• TechNet Forum http://aka.ms/technetforum
http://aka.ms/td2015_again
TechDays Korea 2015에서 놓치신 세션은
Microsoft 기술 동영상 커뮤니티 Channel 9에서
추후에 다시 보실 수 있습니다.
1 von 79

Recomendados

김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019 von
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
3.2K views78 Folien
『DirectX 12를 이용한 3D 게임 프로그래밍 입문』 - 맛보기 von
『DirectX 12를 이용한 3D 게임 프로그래밍 입문』 - 맛보기『DirectX 12를 이용한 3D 게임 프로그래밍 입문』 - 맛보기
『DirectX 12를 이용한 3D 게임 프로그래밍 입문』 - 맛보기복연 이
6.1K views253 Folien
C++20 Key Features Summary von
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features SummaryChris Ohk
9.9K views77 Folien
C++17 Key Features Summary - Ver 2 von
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2Chris Ohk
17.6K views83 Folien
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012 von
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
16.1K views53 Folien
레퍼런스만 알면 언리얼 엔진이 제대로 보인다 von
레퍼런스만 알면 언리얼 엔진이 제대로 보인다레퍼런스만 알면 언리얼 엔진이 제대로 보인다
레퍼런스만 알면 언리얼 엔진이 제대로 보인다Lee Dustin
7.3K views55 Folien

Más contenido relacionado

Was ist angesagt?

모던 C++ 정리 von
모던 C++ 정리모던 C++ 정리
모던 C++ 정리Hansol Kang
147 views30 Folien
포트폴리오에서 사용한 모던 C++ von
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++KWANGIL KIM
673 views53 Folien
파이썬 플라스크 이해하기 von
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
19.8K views174 Folien
초심자를 위한 도커 소개 및 입문 von
초심자를 위한 도커 소개 및 입문초심자를 위한 도커 소개 및 입문
초심자를 위한 도커 소개 및 입문Daniel Seo
2.6K views62 Folien
Multiplayer Game Sync Techniques through CAP theorem von
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremSeungmo Koo
11.8K views64 Folien
게임 분산 서버 구조 von
게임 분산 서버 구조게임 분산 서버 구조
게임 분산 서버 구조Hyunjik Bae
37.7K views35 Folien

Was ist angesagt?(20)

포트폴리오에서 사용한 모던 C++ von KWANGIL KIM
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++
KWANGIL KIM673 views
파이썬 플라스크 이해하기 von Yong Joon Moon
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
Yong Joon Moon19.8K views
초심자를 위한 도커 소개 및 입문 von Daniel Seo
초심자를 위한 도커 소개 및 입문초심자를 위한 도커 소개 및 입문
초심자를 위한 도커 소개 및 입문
Daniel Seo2.6K views
Multiplayer Game Sync Techniques through CAP theorem von Seungmo Koo
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theorem
Seungmo Koo11.8K views
게임 분산 서버 구조 von Hyunjik Bae
게임 분산 서버 구조게임 분산 서버 구조
게임 분산 서버 구조
Hyunjik Bae37.7K views
Modern C++ 프로그래머를 위한 CPP11/14 핵심 von 흥배 최
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
흥배 최46.7K views
송창규, unity build로 빌드타임 반토막내기, NDC2010 von devCAT Studio, NEXON
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
devCAT Studio, NEXON32.1K views
게임서버프로그래밍 #8 - 성능 평가 von Seungmo Koo
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가
Seungmo Koo7.6K views
스프링캠프 2016 발표 - Deep dive into spring boot autoconfiguration von 수홍 이
스프링캠프 2016 발표 - Deep dive into spring boot autoconfiguration스프링캠프 2016 발표 - Deep dive into spring boot autoconfiguration
스프링캠프 2016 발표 - Deep dive into spring boot autoconfiguration
수홍 이7.1K views
クロージャデザインパターン von Moriharu Ohzu
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu19.6K views
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012 von Esun Kim
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
Esun Kim21.2K views
Form認証で学ぶSpring Security入門 von Ryosuke Uchitate
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
Ryosuke Uchitate11.2K views
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기 von Chris Ohk
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
선린인터넷고등학교 2021 알고리즘 컨퍼런스 - Rust로 알고리즘 문제 풀어보기
Chris Ohk1.5K views
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library von DongMin Choi
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
[C++ Korea 2nd Seminar] Ranges for The Cpp Standard Library
DongMin Choi2.4K views
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019 von devCAT Studio, NEXON
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
devCAT Studio, NEXON14.1K views
A Brief Introduction to React.js von Doug Neiner
A Brief Introduction to React.jsA Brief Introduction to React.js
A Brief Introduction to React.js
Doug Neiner5.8K views
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012 von devCAT Studio, NEXON
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
190406 신입 클라이언트 프로그래머 1개월차까지 이야기 von KWANGIL KIM
190406 신입 클라이언트 프로그래머 1개월차까지 이야기190406 신입 클라이언트 프로그래머 1개월차까지 이야기
190406 신입 클라이언트 프로그래머 1개월차까지 이야기
KWANGIL KIM2K views
테라로 살펴본 MMORPG의 논타겟팅 시스템 von QooJuice
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
QooJuice3.3K views

Destacado

[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기 von
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기Chris Ohk
11.8K views71 Folien
[C++ Korea 2nd Seminar] C++17 Key Features Summary von
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features SummaryChris Ohk
10.5K views79 Folien
C++ Programming - 14th Study von
C++ Programming - 14th StudyC++ Programming - 14th Study
C++ Programming - 14th StudyChris Ohk
1.4K views13 Folien
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30 von
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30Chris Ohk
2.1K views67 Folien
C++ Programming - 11th Study von
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th StudyChris Ohk
1.1K views18 Folien
Data Structure - 2nd Study von
Data Structure - 2nd StudyData Structure - 2nd Study
Data Structure - 2nd StudyChris Ohk
1.5K views68 Folien

Destacado(20)

[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기 von Chris Ohk
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
[C++ Korea 3rd Seminar] 새 C++은 새 Visual Studio에, 좌충우돌 마이그레이션 이야기
Chris Ohk11.8K views
[C++ Korea 2nd Seminar] C++17 Key Features Summary von Chris Ohk
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary
Chris Ohk10.5K views
C++ Programming - 14th Study von Chris Ohk
C++ Programming - 14th StudyC++ Programming - 14th Study
C++ Programming - 14th Study
Chris Ohk1.4K views
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30 von Chris Ohk
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
Chris Ohk2.1K views
C++ Programming - 11th Study von Chris Ohk
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th Study
Chris Ohk1.1K views
Data Structure - 2nd Study von Chris Ohk
Data Structure - 2nd StudyData Structure - 2nd Study
Data Structure - 2nd Study
Chris Ohk1.5K views
Data Structure - 1st Study von Chris Ohk
Data Structure - 1st StudyData Structure - 1st Study
Data Structure - 1st Study
Chris Ohk5.1K views
게임 프로그래밍 기초 공부법 von Chris Ohk
게임 프로그래밍 기초 공부법게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법
Chris Ohk60.3K views
[C++ Korea] Effective Modern C++ Study, Item 11 - 13 von Chris Ohk
[C++ Korea] Effective Modern C++ Study, Item 11 - 13[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
Chris Ohk1.8K views
C++ Programming - 4th Study von Chris Ohk
C++ Programming - 4th StudyC++ Programming - 4th Study
C++ Programming - 4th Study
Chris Ohk1.6K views
Akamai Korea - Tech Day (2015/03/11) HTTP/2 von Brandon Kang
Akamai Korea - Tech Day (2015/03/11) HTTP/2Akamai Korea - Tech Day (2015/03/11) HTTP/2
Akamai Korea - Tech Day (2015/03/11) HTTP/2
Brandon Kang6.1K views
2013 C++ Study For Students #1 von Chris Ohk
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
Chris Ohk4.5K views
C++ Programming - 13th Study von Chris Ohk
C++ Programming - 13th StudyC++ Programming - 13th Study
C++ Programming - 13th Study
Chris Ohk993 views
C++ Programming - 9th Study von Chris Ohk
C++ Programming - 9th StudyC++ Programming - 9th Study
C++ Programming - 9th Study
Chris Ohk1.1K views
C++ Programming - 10th Study von Chris Ohk
C++ Programming - 10th StudyC++ Programming - 10th Study
C++ Programming - 10th Study
Chris Ohk1.4K views
C++ Programming - 8th Study von Chris Ohk
C++ Programming - 8th StudyC++ Programming - 8th Study
C++ Programming - 8th Study
Chris Ohk1.1K views
C++ Programming - 7th Study von Chris Ohk
C++ Programming - 7th StudyC++ Programming - 7th Study
C++ Programming - 7th Study
Chris Ohk1.6K views
MSBuild + Git + Jenkins von 선협 이
MSBuild + Git + JenkinsMSBuild + Git + Jenkins
MSBuild + Git + Jenkins
선협 이15.3K views
C++ Programming - 12th Study von Chris Ohk
C++ Programming - 12th StudyC++ Programming - 12th Study
C++ Programming - 12th Study
Chris Ohk1.7K views
[NHN_NEXT] DirectX Tutorial 강의 자료 von MinGeun Park
[NHN_NEXT] DirectX Tutorial 강의 자료[NHN_NEXT] DirectX Tutorial 강의 자료
[NHN_NEXT] DirectX Tutorial 강의 자료
MinGeun Park5.9K views

Similar a [TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기

HI-ARC PS 101 von
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101Jae-yeol Lee
140 views48 Folien
불어오는 변화의 바람, From c++98 to c++11, 14 von
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 명신 김
160 views54 Folien
Deview 2019 눈발자국 von
Deview 2019 눈발자국Deview 2019 눈발자국
Deview 2019 눈발자국hanbeom Park
44 views55 Folien
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계 von
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계Sungkyun Kim
17.4K views48 Folien
[C++ Korea] Effective Modern C++ Study item14 16 +신촌 von
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌Seok-joon Yun
2.8K views52 Folien
06장 함수 von
06장 함수06장 함수
06장 함수유석 남
1.7K views32 Folien

Similar a [TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기(20)

불어오는 변화의 바람, From c++98 to c++11, 14 von 명신 김
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
명신 김160 views
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계 von Sungkyun Kim
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
Sungkyun Kim17.4K views
[C++ Korea] Effective Modern C++ Study item14 16 +신촌 von Seok-joon Yun
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
Seok-joon Yun2.8K views
06장 함수 von 유석 남
06장 함수06장 함수
06장 함수
유석 남1.7K views
C Language I von Suho Kwon
C Language IC Language I
C Language I
Suho Kwon199 views
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013 von Esun Kim
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
Esun Kim7K views
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기 von Jaeseung Ha
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
Jaeseung Ha4.8K views
Programming skills 1부 von JiHyung Lee
Programming skills 1부Programming skills 1부
Programming skills 1부
JiHyung Lee7.4K views
About Visual C++ 10 von 흥배 최
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
흥배 최1.5K views
Modern C++의 타입 추론과 람다, 컨셉 von HyunJoon Park
Modern C++의 타입 추론과 람다, 컨셉Modern C++의 타입 추론과 람다, 컨셉
Modern C++의 타입 추론과 람다, 컨셉
HyunJoon Park205 views
Boost라이브러리의내부구조 20151111 서진택 von JinTaek Seo
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
JinTaek Seo860 views
[NDC2016] TERA 서버의 Modern C++ 활용기 von Sang Heon Lee
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
Sang Heon Lee6.8K views
C++ 프로그래밍 2014-2018년 기말시험 기출문제 von Lee Sang-Ho
C++ 프로그래밍 2014-2018년 기말시험 기출문제C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제
Lee Sang-Ho2.4K views
Api design for c++ 6장 von Ji Hun Kim
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장
Ji Hun Kim2.6K views

Más de Chris Ohk

인프콘 2022 - Rust 크로스 플랫폼 프로그래밍 von
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍Chris Ohk
2.2K views44 Folien
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들 von
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들Chris Ohk
31.3K views44 Folien
Momenti Seminar - 5 Years of RosettaStone von
Momenti Seminar - 5 Years of RosettaStoneMomenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStoneChris Ohk
1.3K views27 Folien
Momenti Seminar - A Tour of Rust, Part 2 von
Momenti Seminar - A Tour of Rust, Part 2Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2Chris Ohk
622 views62 Folien
Momenti Seminar - A Tour of Rust, Part 1 von
Momenti Seminar - A Tour of Rust, Part 1Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1Chris Ohk
795 views45 Folien
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021 von
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021Chris Ohk
766 views48 Folien

Más de Chris Ohk(20)

인프콘 2022 - Rust 크로스 플랫폼 프로그래밍 von Chris Ohk
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
Chris Ohk2.2K views
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들 von Chris Ohk
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
Chris Ohk31.3K views
Momenti Seminar - 5 Years of RosettaStone von Chris Ohk
Momenti Seminar - 5 Years of RosettaStoneMomenti Seminar - 5 Years of RosettaStone
Momenti Seminar - 5 Years of RosettaStone
Chris Ohk1.3K views
Momenti Seminar - A Tour of Rust, Part 2 von Chris Ohk
Momenti Seminar - A Tour of Rust, Part 2Momenti Seminar - A Tour of Rust, Part 2
Momenti Seminar - A Tour of Rust, Part 2
Chris Ohk622 views
Momenti Seminar - A Tour of Rust, Part 1 von Chris Ohk
Momenti Seminar - A Tour of Rust, Part 1Momenti Seminar - A Tour of Rust, Part 1
Momenti Seminar - A Tour of Rust, Part 1
Chris Ohk795 views
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021 von Chris Ohk
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Evolving Reinforcement Learning Algorithms, JD. Co-Reyes et al, 2021
Chris Ohk766 views
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021 von Chris Ohk
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
Adversarially Guided Actor-Critic, Y. Flet-Berliac et al, 2021
Chris Ohk1K views
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020 von Chris Ohk
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
Agent57: Outperforming the Atari Human Benchmark, Badia, A. P. et al, 2020
Chris Ohk1K views
Proximal Policy Optimization Algorithms, Schulman et al, 2017 von Chris Ohk
Proximal Policy Optimization Algorithms, Schulman et al, 2017Proximal Policy Optimization Algorithms, Schulman et al, 2017
Proximal Policy Optimization Algorithms, Schulman et al, 2017
Chris Ohk844 views
Trust Region Policy Optimization, Schulman et al, 2015 von Chris Ohk
Trust Region Policy Optimization, Schulman et al, 2015Trust Region Policy Optimization, Schulman et al, 2015
Trust Region Policy Optimization, Schulman et al, 2015
Chris Ohk651 views
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015 von Chris Ohk
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
Continuous Control with Deep Reinforcement Learning, lillicrap et al, 2015
Chris Ohk1.1K views
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기 von Chris Ohk
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
GDG Gwangju DevFest 2019 - <하스스톤> 강화학습 환경 개발기
Chris Ohk1.1K views
[RLKorea] <하스스톤> 강화학습 환경 개발기 von Chris Ohk
[RLKorea] <하스스톤> 강화학습 환경 개발기[RLKorea] <하스스톤> 강화학습 환경 개발기
[RLKorea] <하스스톤> 강화학습 환경 개발기
Chris Ohk2.1K views
[NDC 2019] 하스스톤 강화학습 환경 개발기 von Chris Ohk
[NDC 2019] 하스스톤 강화학습 환경 개발기[NDC 2019] 하스스톤 강화학습 환경 개발기
[NDC 2019] 하스스톤 강화학습 환경 개발기
Chris Ohk7K views
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지 von Chris Ohk
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
[델리만주] 대학원 캐슬 - 석사에서 게임 프로그래머까지
Chris Ohk2K views
디미고 특강 - 개발을 시작하려는 여러분에게 von Chris Ohk
디미고 특강 - 개발을 시작하려는 여러분에게디미고 특강 - 개발을 시작하려는 여러분에게
디미고 특강 - 개발을 시작하려는 여러분에게
Chris Ohk1.6K views
청강대 특강 - 프로젝트 제대로 해보기 von Chris Ohk
청강대 특강 - 프로젝트 제대로 해보기청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기
Chris Ohk3.2K views
[NDC 2018] 유체역학 엔진 개발기 von Chris Ohk
[NDC 2018] 유체역학 엔진 개발기[NDC 2018] 유체역학 엔진 개발기
[NDC 2018] 유체역학 엔진 개발기
Chris Ohk12.4K views
My Way, Your Way von Chris Ohk
My Way, Your WayMy Way, Your Way
My Way, Your Way
Chris Ohk1.7K views
Re:Zero부터 시작하지 않는 오픈소스 개발 von Chris Ohk
Re:Zero부터 시작하지 않는 오픈소스 개발Re:Zero부터 시작하지 않는 오픈소스 개발
Re:Zero부터 시작하지 않는 오픈소스 개발
Chris Ohk3.4K views

Último

Exploring Deep Learning Acceleration Technology Embedded in LLMs von
Exploring Deep Learning Acceleration Technology Embedded in LLMsExploring Deep Learning Acceleration Technology Embedded in LLMs
Exploring Deep Learning Acceleration Technology Embedded in LLMsTae Young Lee
26 views53 Folien
클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략 von
클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략
클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략Open Source Consulting
111 views25 Folien
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기 von
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기Jinkyoung Kim
46 views139 Folien
AD의 TAD와 협업.pptx von
AD의 TAD와 협업.pptxAD의 TAD와 협업.pptx
AD의 TAD와 협업.pptxVisual Tech Dev
50 views24 Folien
CES 처음 가는 분을 위한 가이드 von
CES 처음 가는 분을 위한 가이드CES 처음 가는 분을 위한 가이드
CES 처음 가는 분을 위한 가이드Minsuk Lee
650 views31 Folien
성능 테스트 von
성능 테스트성능 테스트
성능 테스트Wonjun Hwang
8 views13 Folien

Último(7)

Exploring Deep Learning Acceleration Technology Embedded in LLMs von Tae Young Lee
Exploring Deep Learning Acceleration Technology Embedded in LLMsExploring Deep Learning Acceleration Technology Embedded in LLMs
Exploring Deep Learning Acceleration Technology Embedded in LLMs
Tae Young Lee26 views
클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략 von Open Source Consulting
클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략
클라우드 네이티브 전환 요소 및 성공적인 쿠버네티스 도입 전략
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기 von Jinkyoung Kim
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
Jinkyoung Kim46 views
CES 처음 가는 분을 위한 가이드 von Minsuk Lee
CES 처음 가는 분을 위한 가이드CES 처음 가는 분을 위한 가이드
CES 처음 가는 분을 위한 가이드
Minsuk Lee650 views

[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기

  • 1. 옥찬호 / 넥슨 (NEXON KOREA), Visual C++ MVP 녹슨 C++ 코드에 모던 C++로 기름칠하기
  • 2. 시작하기 전에… • 모던 C++이란 C++11/14를 말합니다. • C++11/14을 통한 개선 뿐만 아니라 기존 C++을 통한 개선 방법도 함께 포함합니다. • 모던 C++을 모르는 분들을 위해 최대한 쉽게 설명합니다. • 예제 코드가 많은 부분을 차지합니다.
  • 4. int _output( FILE* stream, char const* format, va_list arguments ) { // ... }
  • 5. #ifdef _UNICODE int _woutput ( #else /* _UNICODE */ int _output ( #endif /* _UNICODE */ FILE* stream, _TCHAR const* format, va_list arguments ) { // ... }
  • 6. #ifdef _UNICODE #ifdef POSITIONAL_PARAMETERS int _woutput_p ( #else /* POSITIONAL_PARAMETERS */ int _woutput ( #endif /* POSITIONAL_PARAMETERS */ #else /* _UNICODE */ #ifdef POSITIONAL_PARAMETERS int _output_p ( #else /* POSITIONAL_PARAMETERS */ int _output ( #endif /* POSITIONAL_PARAMETERS */ #endif /* _UNICODE */ FILE* stream, _TCHAR const* format, va_list arguments ) { ... }
  • 7. IFileDialog *pfd = NULL; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pfd)); if (SUCCEEDED(hr)) { IFileDialogEvents *pfde = NULL; hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde)); if (SUCCEEDED(hr)) { DWORD dwCookie; hr = pfd->Advise(pfde, &dwCookie); if (SUCCEEDED(hr)) { DWORD dwFlags; hr = pfd->GetOptions(&dwFlags); if (SUCCEEDED(hr)) { hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM); if (SUCCEEDED(hr)) { hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes); if (SUCCEEDED(hr)) { hr = pfd->SetFileTypeIndex(INDEX_WORDDOC); if (SUCCEEDED(hr)) { hr = pfd->SetDefaultExtension(L"doc;docx"); if (SUCCEEDED(hr)) {
  • 9. 고치고 싶다… 하지만 • 이미 고치기엔 길어져버린 코드 • 어디서부터 손을 써야 할 지 모름 • 코드는 점점 산으로… • 아 귀찮다… ㅁㄴㅇㄹ
  • 11. 어디에 기름칠을 해볼까? • 전처리기 • 리소스 관리 • 함수 • 타입, 반복문 • 기타 등등…
  • 13. 조건부 컴파일 • #if, #ifdef, #ifndef, #elif, #else, … • 많이 쓸수록 복잡해진다. • 많이 쓸수록 이해하기 어렵다. • 많이 쓸수록 유지보수하기 어렵다.
  • 14. #ifdef _UNICODE int _woutput ( #else /* _UNICODE */ int _output ( #endif /* _UNICODE */ FILE* stream, _TCHAR const* format, va_list arguments ) { // ... }
  • 15. template <typename T> static int common_output( FILE* stream, T const* format, va_list arguments ) { // ... } int _output(FILE* stream, char const* format, va_list const arguments) { return common_output(stream, format, arguments); } int _woutput(FILE* stream, wchar_t const* format, va_list const arguments) { return common_output(stream, format, arguments); }
  • 16. // Check windows #if _WIN32 || _WIN64 #if _WIN64 #define ENVIRONMENT64 #else #define ENVIRONMENT32 #endif #endif // Check GCC #if __GNUC__ #if __x86_64__ || __ppc64__ #define ENVIRONMENT64 #else #define ENVIRONMENT32 #endif #endif
  • 17. 케이스 바이 케이스 • 타입에 따른 조건부 컴파일은 함수 템플릿을 통해 개선한다. • 하지만 #ifdef를 사용해야 되는 경우도 있다. • 32비트 vs 64비트 코드 • DEBUG 모드 vs Non-DEBUG 모드 • 컴파일러, 플랫폼, 언어에 따라 다른 코드 • 반드시 사용해야 된다면, 코드를 단순화하는 것이 좋다. • 중첩 #ifdef를 피하고, 함수의 일부를 조건부 컴파일에 넣지 않도록 한다.
  • 18. 매크로 • #define … • 변수 대신 사용하는 매크로 : #define RED 1 • 함수 대신 사용하는 매크로 : #define SQUARE(x) ((x) * (x)) • 수많은 문제를 일으키는 장본인 • 컴파일러가 타입에 대한 정보를 갖기 전에 계산됨 • 필요 이상으로 많이 사용
  • 20. #define red 0 #define orange 1 #define yellow 2 #define green 3 #define blue 4 #define purple 5 #define hot_pink 6 void f() { unsigned orange = 0xff9900; } warning C4091: '' : ignored on left of 'unsigned int' when no variable is declared error C2143: syntax error : missing ';' before 'constant' error C2106: '=' : left operand must be l-value
  • 21. #define red 0 #define orange 1 #define yellow 2 #define green 3 #define blue 4 #define purple 5 #define hot_pink 6 void f() { unsigned 2 = 0xff00ff; } warning C4091: '' : ignored on left of 'unsigned int' when no variable is declared error C2143: syntax error : missing ';' before 'constant' error C2106: '=' : left operand must be l-value
  • 22. #define RED 0 #define ORANGE 1 #define YELLOW 2 #define GREEN 3 #define BLUE 4 #define PURPLE 5 #define HOT_PINK 6 void g(int color); // valid values are 0 through 6 void f() { g(HOT_PINK); // Ok g(9000); // Not ok, but compiler can’t tell }
  • 23. enum color_type { red = 0, orange = 1, yellow = 2, green = 3, blue = 4, purple = 5, hot_pink = 6 };
  • 24. enum color_type { red, orange, yellow, green, blue, purple, hot_pink }; void g(color_type color); void f() { g(hot_pink); // Ok g(9000); // Not ok, compiler will report error } error C2664: 'void g(color_type)' : cannot convert argument 1 from 'int' to 'color_type'
  • 25. enum color_type { red, orange, yellow, green, blue, purple, hot_pink }; void f() { int x = red; // Ugh int x = red + orange; // Double ugh }
  • 26. enum color_type { red, orange, yellow, green, blue, purple, hot_pink }; enum traffic_light_state { red, yellow, green }; error C2365: 'red' : redefinition; previous definition was 'enumerator‘ error C2365: 'yellow' : redefinition; previous definition was 'enumerator‘ error C2365: 'green' : redefinition; previous definition was 'enumerator'
  • 27. 열거체의 문제점 • 묵시적인 int 변환 • 열거체의 타입을 명시하지 못함 • 이상한 범위 적용 → 열거체 클래스(enum class)의 등장!
  • 28. enum class color_type { red, orange, yellow, green, blue, purple, hot_pink }; void g(color_type color); void f() { g(color_type::red); }
  • 29. enum class color_type { red, orange, yellow, green, blue, purple, hot_pink }; void g(color_type color); void f() { int x = color_type::hot_pink; } error C2440: 'initializing' : cannot convert from 'color_type' to 'int'
  • 30. enum class color_type { red, orange, yellow, green, blue, purple, hot_pink }; void g(color_type color); void f() { int x = static_cast<int>(color_type::hot_pink); }
  • 31. 열거체 클래스를 사용하자 • 묵시적인 int 변환 → 명시적인 int 변환 • 열거체의 타입을 명시하지 못함 → 타입 명시 가능 • 이상한 범위 적용 → 범위 지정 연산자를 통해 구분
  • 33. #define make_char_lowercase(c) ((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) void make_string_lowercase(char* s) { while (make_char_lowercase(*s++)) ; }
  • 34. #define make_char_lowercase(c) ((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) void make_string_lowercase(char* s) { while (((*s++) = (((*s++) >= 'A') && ((*s++) <= 'Z')) ? ((*s++) - 'A' + 'a') : (*s++))) ; }
  • 35. // Old, ugly macro implementation: #define make_char_lowercase(c) ((c) = (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) // New, better function implementation: inline char make_char_lowercase(char& c) { if (c > 'A' && c < 'Z') { c = c - 'A' + 'a'; } return c; }
  • 36. 열거체, 함수를 사용하자 • 변수 대신 사용하는 매크로에는 열거체를 사용하자. • 열거체에서 발생할 수 있는 문제는 enum class로 해결할 수 있다. • 열거체 대신 ‘static const’ 변수를 사용하는 방법도 있다. • 함수 대신 사용하는 매크로에는 함수를 사용하자. • 읽기 쉽고, 유지보수하기 쉽고, 디버깅하기 쉽다. • 성능에 따른 오버헤드도 없다.
  • 38. IFileDialog *pfd = NULL; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pfd)); if (SUCCEEDED(hr)) { IFileDialogEvents *pfde = NULL; hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde)); if (SUCCEEDED(hr)) { DWORD dwCookie; hr = pfd->Advise(pfde, &dwCookie); if (SUCCEEDED(hr)) { DWORD dwFlags; hr = pfd->GetOptions(&dwFlags); if (SUCCEEDED(hr)) { hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM); if (SUCCEEDED(hr)) { hr = pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes); if (SUCCEEDED(hr)) { hr = pfd->SetFileTypeIndex(INDEX_WORDDOC); if (SUCCEEDED(hr)) { hr = pfd->SetDefaultExtension(L"doc;docx"); if (SUCCEEDED(hr)) {
  • 39. IFileDialog *pfd = NULL; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, IID_PPV_ARGS(&pfd)); if (FAILED(hr)) return hr; IFileDialogEvents *pfde = NULL; hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde)); if (FAILED(hr)) return hr; DWORD dwCookie; hr = pfd->Advise(pfde, &dwCookie); if (FAILED(hr)) return hr; DWORD dwFlags; hr = pfd->GetOptions(&dwFlags); if (FAILED(hr)) return hr;
  • 41. void ExampleWithoutRAII() { std::FILE* file_handle = std::fopen("logfile.txt", "w+"); if (file_handle == nullptr) throw std::runtime_error("File couldn't open!"); try { if (std::fputs("Hello, Log File!", file_handle) == EOF) throw std::runtime_error("File couldn't write!"); // continue writing to logfile.txt ... do not return // prematurely, as cleanup happens at the end of this function } catch (...) { std::fclose(file_handle); throw; } std::fclose(file_handle); }
  • 42. RAII • 자원 획득은 초기화다 (Resource Acquisition Is Initialization) • 객체의 생성에 맞춰 메모리와 시스템 리소스를 자동으로 할당 • 객체의 소멸에 맞춰 메모리와 시스템 리소스를 자동으로 해제 → 생성자 안에서 리소스를 할당하고, 소멸자에서 리소스를 해제
  • 43. void ExampleWithRAII() { // open file (acquire resource) File logFile("logfile.txt"); logFile.Write("Hello, Log File!"); // continue writing to logfile.txt ... } File::File(const char* filename) : m_file_handle(std::fopen(filename, "w+")) { if (m_file_handle == NULL) throw openError(); } File::~File() { std::fclose(m_file_handle); }
  • 44. void ExampleWithRAII() { // open file (acquire resource) File* logFile = new File("logfile.txt"); logFile->Write("Hello, Log File!"); // continue writing to logfile.txt ... } File::File(const char* filename) : m_file_handle(std::fopen(filename, "w+")) { if (m_file_handle == NULL) throw openError(); } File::~File() { std::fclose(m_file_handle); }
  • 45. 다시 발생하는 문제 • 파일 입출력과 관련한 예외 처리를 간편하게 하기 위해 File 클래스를 만들어 생성자와 소멸자로 처리했다. • 하지만, 정작 File 클래스를 동적으로 할당하는 경우 소멸자가 호출되지 않아 파일을 닫지 않는 문제가 발생한다. • 좋은 방법이 없을까? → 스마트 포인터(Smart Pointer)의 등장!
  • 46. 스마트 포인터 • 좀 더 똑똑한 포인터 • 스마트 포인터를 사용하면 명시적으로 해제할 필요가 없다. • 사용하는 이유 • 적은 버그, 자동 청소, 자동 초기화 • Dangling 포인터 발생 X, Exception 안전 • 효율성
  • 47. void ExampleWithRAII() { // open file (acquire resource) std::unique_ptr<File> logFile = std::make_unique<File>("logfile.txt"); logFile->Write("Hello, Log File!"); // continue writing to logfile.txt ... } File::File(const char* filename) : m_file_handle(std::fopen(filename, "w+")) { if (m_file_handle == NULL) throw openError(); } File::~File() { std::fclose(m_file_handle); }
  • 48. 스마트 포인터의 종류 • 경우에 따라 여러 종류의 스마트 포인터를 사용할 수 있다. • shared_ptr : 객체의 소유권을 복사할 수 있는 포인터 (여러 shared_ptr 객체가 같은 포인터 객체를 가리킬 수 있음) • unique_ptr : 객체의 소유권을 복사할 수 없는 포인터 (하나의 unique_ptr 객체만이 하나의 포인터 객체를 가리킬 수 있음)
  • 49. std::unique_ptr ptrA Song 개체 ptrA Song 개체 ptrB auto ptrA = std::make_unique<Song>(L"Diana Krall", L"The Look of Love"); auto ptrB = std::move(ptrA);
  • 50. std::unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title) { // Implicit move operation into the variable that stores the result. return std::make_unique<Song>(artist, title); } void MakeSongs() { // Create a new unique_ptr with a new object. auto song = std::make_unique<Song>(L"Mr. Children", L"Namonaki Uta"); // Use the unique_ptr. std::vector<std::wstring> titles = { song->title }; // Move raw pointer from one unique_ptr to another. std::unique_ptr<Song> song2 = std::move(song); // Obtain unique_ptr from function that returns by value. auto song3 = SongFactory(L"Michael Jackson", L"Beat It"); }
  • 51. std::shared_ptr MyClass 제어 블록 참조 개수 = 1 개체에 대한 포인터 제어 블록에 대한 포인터 p1
  • 52. std::shared_ptr MyClass 제어 블록 참조 개수 = 2 개체에 대한 포인터 제어 블록에 대한 포인터 p1 개체에 대한 포인터 제어 블록에 대한 포인터 p2
  • 53. // Use make_shared function when possible. auto sp1 = std::make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You"); // Ok, but slightly less efficient. // Note: Using new expression as constructor argument // creates no named variable for other code to access. std::shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance")); // When initialization must be separate from declaration, e.g. class members, // initialize with nullptr to make your programming intent explicit. std::shared_ptr<Song> sp5(nullptr); //Equivalent to: shared_ptr<Song> sp5; //... sp5 = std::make_shared<Song>(L"Elton John", L"I'm Still Standing");
  • 54. 리소스 관리는 스마트 포인터로 • RAII를 사용하자! • 읽고, 쓰고, 유지보수하기 쉽다. • 자원 관리에 대한 걱정을 할 필요가 없다. • C++ 코드 품질을 향상시키는 가장 쉬운 방법! • 기왕이면 스마트 포인터로! • shared_ptr • unique_ptr
  • 56. std::vector<int>::const_iterator iter = cardinal.begin(); std::vector<int>::const_iterator iter_end = cardinal.end(); int total_elements = 1; while (iter != iter_end) { total_elements *= *iter; ++iter; }
  • 57. template <typename T> struct product { product(T& storage) : value(storage) {} template<typename V> void operator()(V& v) { value *= v; } T& value; }; std::vector<int> cardinal; int total_elements = 1; for_each(cardinal.begin(), cardinal.end(), product<int>(total_elements));
  • 58. int total_elements = 1; for_each(cardinal.begin(), cardinal.end(), [&total_elements](int i) { total_elements *= i; });
  • 59. struct mod { mod(int m) : modulus(m) {} int operator()(int v) { return v % modulus; } int modulus; }; int my_mod = 8; std::transform(in.begin(), in.end(), out.begin(), mod(my_mod)); int my_mod = 8; transform(in.begin(), in.end(), out.begin(), [my_mod](int v) -> int { return v % my_mod; }); Functor Lambda Expression
  • 60. 람다식 [my_mod] (int v) -> int { return v % my_mod; } 개시자 (Introducer Capture) 인자 (Arguments) 반환 타입 (Return Type) 함수의 몸통 (Statement)
  • 61. int x = 10, y = 20; [] {}; // 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
  • 62. 1 2 2 void fa(int x, function<void(void)> f) { ++x; f(); } void fb(int x, function<void(int)> f) { ++x; f(x); } void fc(int &x, function<void(void)> f) { ++x; f(); } int x = 1; fa(x, [x] { cout << x << endl; }); fb(x, [](int x) { cout << x << endl; }); fc(x, [&x] { cout << x << endl; });
  • 63. WNDCLASSEX wcex; wcex.lpfnWndProc= [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT { switch (message) { case WM_COMMAND: EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL { char szText[256]; GetWindowTextA(hwnd, szText, 256); cout << szText << endl; return TRUE; }, 0);
  • 64. HANDLE hT = CreateThread(NULL, 0, [](LPVOID lpThreadParameter) -> DWORD { for (int i = 0; i < 1000; i++) { this_thread::sleep_for(milliseconds{ 10 }); cout << i << endl; } return 0; }, NULL, 0, NULL);
  • 65. 람다식을 사용하자 • 짧고, 간결하고, while 문과 같은 행사 코드 없이 깔끔하게 작성할 수 있다. • 수십줄의 코드를 1~2줄로 간추릴 수 있다. • Functor, Callback Function을 대체해서 사용할 수 있다. • 반복적으로 사용하는 함수가 아니라면 람다식을 사용하자!
  • 67. auto 키워드 • 컴파일 타임에 타입을 추론해 어떤 타입인지 결정한다. • 컴파일 타임에 추론이 불가능하다면, 오류가 발생한다. std::vector<std::tuple<std::string, int, double>> vStudents; for (std::vector<std::tuple<std::string, int, double>>::iterator iter = vStudents.begin(); iter != vStudents.end(); ++iter) { … } std::vector<std::tuple<std::string, int, double>> vStudents; for (auto iter = vStudents.begin(); iter != vStudents.end(); ++iter) { … }
  • 68. 범위 기반 for문 int arr[] = { 1, 2, 3, 4, 5 }; for (int i = 0; i < 5; ++i) std::cout << arr[i] << std::endl; return 0; } int arr[] = { 1, 2, 3, 4, 5 }; for (auto& i : arr) std::cout << i << std::endl; return 0; }
  • 69. 정리 // circle and shape are user-defined types circle* p = new circle(42); vector<shape*> v = load_shapes(); for (vector<circle*>::iterator i = v.begin(); i != v.end(); ++i) { if (*i && **i == *p) cout << **i << " is a matchn"; } for (vector<circle*>::iterator i = v.begin(); i != v.end(); ++i) { delete *i; // not exception safe } delete p;
  • 70. 정리 // circle and shape are user-defined types auto p = make_shared<circle>(42); vector<shared_ptr<shape>> v = load_shapes(); for_each(begin(v), end(v), [&](const shared_ptr<shape>& s) { if (s && *s == *p) cout << *s << " is a matchn"; });
  • 71. 정리 • 대체할 수 있는 조건부 컴파일은 템플릿으로 기름칠! • 매크로는 가급적 사용하지 말고 열거체와 함수로 기름칠! • 리소스 관리에는 RAII, 기왕이면 스마트 포인터로 기름칠! • 일회성으로 사용하는 함수는 람다식으로 기름칠! • 복잡한 타입에는 auto로 기름칠! • 반복 횟수에 고통받지 말고 범위 기반 for문으로 기름칠!
  • 72. 정리 • 모던 C++을 통해 대체할 수 있는 코드는 많습니다! (하지만 제한된 시간으로 인해 …) • 다음 사이트에서 모던 C++ 예제 코드를 확인하실 수 있습니다. http://www.github.com/utilForever/ModernCpp • C++ 핵심 가이드라인 • 영문 : https://github.com/isocpp/CppCoreGuidelines • 한글 : https://github.com/CppKorea/CppCoreGuidelines
  • 73. Quiz
  • 74. #include <iostream> #include <memory> #include <vector> class C { public: void foo() { std::cout << "A"; } void foo() const { std::cout << "B"; } }; struct S { std::vector<C> v; std::unique_ptr<C> u; C* const p; S() : v(1), u(new C()), p(u.get()) {} }; Quiz #1 int main() { S s; const S& r = s; s.v[0].foo(); s.u->foo(); s.p->foo(); r.v[0].foo(); r.u->foo(); r.p->foo(); } AAABAA
  • 75. #include <iostream> struct A { A() { std::cout << "A"; } A(const A& a) { std::cout << "B"; } virtual void f() { std::cout << "C"; } }; int main() { A a[2]; for (auto x : a) { x.f(); } } Quiz #2 AABCBC
  • 76. #include <iostream> struct A { A() { std::cout << "A"; } A(const A& a) { std::cout << "B"; } virtual void f() { std::cout << "C"; } }; int main() { A a[2]; for (auto& x : a) { x.f(); } } Quiz #3 AACC
  • 78. 감사합니다. • MSDN Forum http://aka.ms/msdnforum • TechNet Forum http://aka.ms/technetforum
  • 79. http://aka.ms/td2015_again TechDays Korea 2015에서 놓치신 세션은 Microsoft 기술 동영상 커뮤니티 Channel 9에서 추후에 다시 보실 수 있습니다.