SlideShare a Scribd company logo
옥찬호 / 넥슨 (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)) {
고치고 싶다… 하지만
• 이미 고치기엔 길어져버린 코드
• 어디서부터 손을 써야 할 지 모름
• 코드는 점점 산으로…
• 아 귀찮다… ㅁㄴㅇㄹ
어디에 기름칠을 해볼까?
• 전처리기
• 리소스 관리
• 함수
• 타입, 반복문
• 기타 등등…
전처리기
조건부 컴파일
• #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에서
추후에 다시 보실 수 있습니다.

More Related Content

What's hot

Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Isaac Jeon
 
Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리
ssuser7c5a40
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2
Chris Ohk
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011Esun Kim
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
Jaeseung Ha
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013Esun Kim
 
C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부
Gwangwhi Mah
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
Jaeseung Ha
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
JinTaek Seo
 
Boost
BoostBoost
C++11
C++11C++11
C++11
선협 이
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11OnGameServer
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features Summary
Chris Ohk
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
흥배 최
 
Let's Go (golang)
Let's Go (golang)Let's Go (golang)
Let's Go (golang)
상욱 송
 
Modern C++의 타입 추론과 람다, 컨셉
Modern C++의 타입 추론과 람다, 컨셉Modern C++의 타입 추론과 람다, 컨셉
Modern C++의 타입 추론과 람다, 컨셉
HyunJoon Park
 
100511 boost&tips 최성기
100511 boost&tips 최성기100511 boost&tips 최성기
100511 boost&tips 최성기
sung ki choi
 
파이썬 스터디 15장
파이썬 스터디 15장파이썬 스터디 15장
파이썬 스터디 15장SeongHyun Ahn
 
C++ Advanced 강의 3주차
C++ Advanced 강의 3주차C++ Advanced 강의 3주차
C++ Advanced 강의 3주차
HyunJoon Park
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
Jongwook Choi
 

What's hot (20)

Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...Nexon Developers Conference 2017 Functional Programming for better code - Mod...
Nexon Developers Conference 2017 Functional Programming for better code - Mod...
 
Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리Refelction의 개념과 RTTR 라이브러리
Refelction의 개념과 RTTR 라이브러리
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
 
C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 
Boost
BoostBoost
Boost
 
C++11
C++11C++11
C++11
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11
 
C++20 Key Features Summary
C++20 Key Features SummaryC++20 Key Features Summary
C++20 Key Features Summary
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
 
Let's Go (golang)
Let's Go (golang)Let's Go (golang)
Let's Go (golang)
 
Modern C++의 타입 추론과 람다, 컨셉
Modern C++의 타입 추론과 람다, 컨셉Modern C++의 타입 추론과 람다, 컨셉
Modern C++의 타입 추론과 람다, 컨셉
 
100511 boost&tips 최성기
100511 boost&tips 최성기100511 boost&tips 최성기
100511 boost&tips 최성기
 
파이썬 스터디 15장
파이썬 스터디 15장파이썬 스터디 15장
파이썬 스터디 15장
 
C++ Advanced 강의 3주차
C++ Advanced 강의 3주차C++ Advanced 강의 3주차
C++ Advanced 강의 3주차
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
 

Similar to [Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)

HI-ARC PS 101
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101
Jae-yeol Lee
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
명신 김
 
Deview 2019 눈발자국
Deview 2019 눈발자국Deview 2019 눈발자국
Deview 2019 눈발자국
hanbeom Park
 
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
Sungkyun Kim
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[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
 
Visual studio 2010
Visual studio 2010Visual studio 2010
Visual studio 2010
MinGeun Park
 
C Language I
C Language IC Language I
C Language ISuho Kwon
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
Jaeseung Ha
 
Programming skills 1부
Programming skills 1부Programming skills 1부
Programming skills 1부
JiHyung Lee
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
흥배 최
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++
KWANGIL KIM
 
Javascript
JavascriptJavascript
Javascript
Hong Hyo Sang
 
DEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptxDEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptx
hanbeom Park
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
Sang Heon Lee
 
C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제
Lee Sang-Ho
 
Api design for c++ 6장
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장Ji Hun Kim
 
Changes in c++0x
Changes in c++0xChanges in c++0x
Changes in c++0x
Sang Yeon Jeon
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 

Similar to [Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호) (20)

HI-ARC PS 101
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
 
Deview 2019 눈발자국
Deview 2019 눈발자국Deview 2019 눈발자국
Deview 2019 눈발자국
 
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
 
06장 함수
06장 함수06장 함수
06장 함수
 
Visual studio 2010
Visual studio 2010Visual studio 2010
Visual studio 2010
 
C Language I
C Language IC Language I
C Language I
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
 
6 function
6 function6 function
6 function
 
Programming skills 1부
Programming skills 1부Programming skills 1부
Programming skills 1부
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++포트폴리오에서 사용한 모던 C++
포트폴리오에서 사용한 모던 C++
 
Javascript
JavascriptJavascript
Javascript
 
DEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptxDEVIEW-FULL-감독판.pptx
DEVIEW-FULL-감독판.pptx
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
 
C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제C++ 프로그래밍 2014-2018년 기말시험 기출문제
C++ 프로그래밍 2014-2018년 기말시험 기출문제
 
Api design for c++ 6장
Api design for c++ 6장Api design for c++ 6장
Api design for c++ 6장
 
Changes in c++0x
Changes in c++0xChanges in c++0x
Changes in c++0x
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 

More from Sang Don Kim

[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016
[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016
[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016
Sang Don Kim
 
[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)
[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)
[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)
Sang Don Kim
 
[TD 2015] Microsoft Azure IaaS v2(최정현)
[TD 2015] Microsoft Azure IaaS v2(최정현)[TD 2015] Microsoft Azure IaaS v2(최정현)
[TD 2015] Microsoft Azure IaaS v2(최정현)
Sang Don Kim
 
[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)
[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)
[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)
Sang Don Kim
 
[Td 2015]두근두근 asp.net 5(한상훈)
[Td 2015]두근두근 asp.net 5(한상훈)[Td 2015]두근두근 asp.net 5(한상훈)
[Td 2015]두근두근 asp.net 5(한상훈)
Sang Don Kim
 
[Td 2015]windows 10 엔터프라이즈 시나리오 part II 보안 및 관리(권순만)
[Td 2015]windows 10 엔터프라이즈 시나리오 part II   보안 및 관리(권순만)[Td 2015]windows 10 엔터프라이즈 시나리오 part II   보안 및 관리(권순만)
[Td 2015]windows 10 엔터프라이즈 시나리오 part II 보안 및 관리(권순만)
Sang Don Kim
 
[Td 2015]windows 10 엔터프라이즈 시나리오 part I 배포 및 이미징(박성기)
[Td 2015]windows 10 엔터프라이즈 시나리오 part I   배포 및 이미징(박성기)[Td 2015]windows 10 엔터프라이즈 시나리오 part I   배포 및 이미징(박성기)
[Td 2015]windows 10 엔터프라이즈 시나리오 part I 배포 및 이미징(박성기)
Sang Don Kim
 
[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)
[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)
[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)
Sang Don Kim
 
[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)
[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)
[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)
Sang Don Kim
 
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)
Sang Don Kim
 
[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)
[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)
[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)
Sang Don Kim
 
[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)
[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)
[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)
Sang Don Kim
 
[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)
[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)
[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)
Sang Don Kim
 
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
Sang Don Kim
 
[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)
[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)
[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)
Sang Don Kim
 
[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)
[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)
[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)
Sang Don Kim
 
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
Sang Don Kim
 
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
Sang Don Kim
 
[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)
[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)
[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)
Sang Don Kim
 
[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)
[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)
[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)
Sang Don Kim
 

More from Sang Don Kim (20)

[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016
[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016
[Td 2015] 국내에서 처음으로 선보이는 microsoft 차세대 서버 운영 체제 windows server 2016
 
[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)
[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)
[TD 2015] windows server에서 만나보는 docker와 windows container(최한홍)
 
[TD 2015] Microsoft Azure IaaS v2(최정현)
[TD 2015] Microsoft Azure IaaS v2(최정현)[TD 2015] Microsoft Azure IaaS v2(최정현)
[TD 2015] Microsoft Azure IaaS v2(최정현)
 
[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)
[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)
[TD2015] 이 시대에 소규모 게임 개발팀이 마소와 함께 살아가는 방법(송용성)
 
[Td 2015]두근두근 asp.net 5(한상훈)
[Td 2015]두근두근 asp.net 5(한상훈)[Td 2015]두근두근 asp.net 5(한상훈)
[Td 2015]두근두근 asp.net 5(한상훈)
 
[Td 2015]windows 10 엔터프라이즈 시나리오 part II 보안 및 관리(권순만)
[Td 2015]windows 10 엔터프라이즈 시나리오 part II   보안 및 관리(권순만)[Td 2015]windows 10 엔터프라이즈 시나리오 part II   보안 및 관리(권순만)
[Td 2015]windows 10 엔터프라이즈 시나리오 part II 보안 및 관리(권순만)
 
[Td 2015]windows 10 엔터프라이즈 시나리오 part I 배포 및 이미징(박성기)
[Td 2015]windows 10 엔터프라이즈 시나리오 part I   배포 및 이미징(박성기)[Td 2015]windows 10 엔터프라이즈 시나리오 part I   배포 및 이미징(박성기)
[Td 2015]windows 10 엔터프라이즈 시나리오 part I 배포 및 이미징(박성기)
 
[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)
[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)
[Td 2015]함께하면 더 좋은 windows 10과 인텔 스카이레이크, 아키텍쳐와 인텔 그래픽스 최적화 살펴보기(하태동)
 
[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)
[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)
[Td 2015]프로그래밍 언어의 f1머신 c++을 타고 windows 10 uwp 앱 개발의 세계로~(유영천)
 
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips &amp; tricks(송기수)
 
[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)
[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)
[Td 2015]치즈케이크 팩토리는 알겠는데, 데이터 팩토리는 뭔가요(한기환)
 
[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)
[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)
[Td 2015]조막만한 화면에서 대박만한 화면까지. 고생 끝 적응(adaptive ui) 시작(권영철)
 
[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)
[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)
[Td 2015]알아두면 핵 이득! vc++로 안드로이드 개발하기(김성엽)
 
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
[Td 2015]박애주의 office 365, 멀티플랫폼과 사랑에 빠지다(최한홍)
 
[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)
[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)
[Td 2015]맨땅에 헤딩하고 터득한 스토어 공략법(돈벌기)(육주용)
 
[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)
[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)
[Td 2015]라즈베리파이에 windows 10 io t core 맛있게 발라 먹기(유정현)
 
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
[Td 2015]디버깅, 어디까지 해봤니 당신이 아마도 몰랐을 디버깅 꿀팁 공개(김희준)
 
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
 
[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)
[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)
[Td 2015]구름 위로 올려 어느 곳에서든 연결되는 서비스 azure 앱 서비스(이종인)
 
[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)
[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)
[Td 2015]각이 다른 mvc6! 그 여섯 번째 이야기!(최지훈)
 

[Td 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)) {
  • 8.
  • 9. 고치고 싶다… 하지만 • 이미 고치기엔 길어져버린 코드 • 어디서부터 손을 써야 할 지 모름 • 코드는 점점 산으로… • 아 귀찮다… ㅁㄴㅇㄹ
  • 10.
  • 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에서 추후에 다시 보실 수 있습니다.