'C++'에 해당되는 글 6건

  1. 2012.02.22 C++ Template, Expression Templates #4 2
  2. 2012.02.21 C++ Template, Expression Templates #3
  3. 2012.02.17 C++ Template, Expression Templates #2
  4. 2012.02.10 C++ Basic Concept, Storage Duration
  5. 2012.02.08 C++ Template, Expression Templates #1 3
  6. 2012.02.07 C++ Basic Concept, One definition rule (ODR) 2

C++ Template, Expression Templates #4

Short Articles 2012. 2. 22. 20:05
표현식 템플릿은 숫자 배열 클래스를 지원하기 위해 고안된 프로그램이 기술입니다
이번 아티클은 다음과 같이 진행합니다
1. 단순한 배열 클래스 구현하여 배열 연산에 대한 문제제기
2. 표현식 템플릿 구현
3. 표현식 템플릿을 아는 랩퍼클래스 구현
4. 실재 표현식 템플릿 사용해서 어떻게 동작하는 방법 추적  
전체 표현식을 다 읽기 전에는 표현식의 일부만 계산하지 않고 전체 계산하기전에 어떤 객체에 무슨 연산이 적용되었는지 기록하는 것이 표현식 템플릿의 핵심입니다

 첫시간에 SArray 단순 배열 클래스를 만들었습니다
두번째에 A_Add, A_Mult, A_Scalar에 대해서 배웠습니다
(스칼라 때문에 A_Traits 이라는 특질클래스도 배웠습니다)
세번째에 Array 클래스와 연산자 배웠습니다

처음으로 돌아가서 배열 연산을 해봅시다

이 연산 부터 알아봅시다
1.2*x
연산자 오버로딩 중에 스칼라와 배열 곱셈연산이 호출됩니다

지저분 하네요 --; 이전에 설명 했습니다
템플릿 인자 추론(template argument deduction)이 되네요
operator* 의 Parameters : Arguments 로 구분하면
T const& s                :               1.2
Array const& b           :               x
T는 double 이고 R2는 SArray
double const& s , Array const& b 입니다
리턴타입
Array<T,A_Mult<T,A_Scalar<T>,R2> > 은  A_Scalar<T>와 R2 곱셈연산 결과를  A_Mult<T,A_Scalar<T>,R2> 가지고 있고 다른 곱셈 및 덧셈에 연산하기 위해 Array 래퍼클래스에 담고 있습니다
해당 객체를 생성자 리턴하는 아주 간결한(?) 코드 입니다
그러니까 A( B(c,d) ) 이런 구문이라고 할까요?
A객체를 생성하려면 B객체를 필요하고 B객체를 생성하려면 c,d 가 필요한경우 입니다

Array<...>(...) 결국 껍데기는  Array 이거이죠. 생성자를 호출한 코드입니다
Array<T,A_Mult<...> >(A_Mult<...>(...) ) Array에 실재 저장 하는 배열클래스를 넣어야 합니다 Array 생성자에 인수가 넣어야 하잖아요 그럼 Array는 끝났습니다 그런데  A_Mult가 남았네요 A_Mult 생성자를 넣어야 합니다
Array<T,A_Mult<T,A_Scalar<T>,R2> >(A_Scalar<T>(s), b.rep())); 그래서 이렇게 나왔습니다

 x*y
두 배열의 곱셈연산이 호출됩니다

이 연산도 설명해드려야 하는 거죠?? ㅡㅡ;
인자추론을 하면
Array<T,R1> const& a   :   x
Array<T,R2> const& b   :   y
T는 double 이고 R1는 SArray R2는 SArray 입니다
두 배열간 곱셈 연산도 생성자 호출인데요 
A( B(c,d) ) 이런형식 입니다
 
1.2*x + x*y
더하기 입니다

이것도 동일합니다 인자추론하면 어떨까요?
Array<T,R1> const& a    :     1.2*x  타입은  Array<double, A_Mult< double ,A_Scalar< double >,SArray> >
Array<T,R2> const& b    :      x*y  타입은   Array< double , A_Mult< double , SArray , SArray > >
T는 double이고 R1는  A_Mult< double ,A_Scalar< double >,SArray> , R2는  A_Mult< double , SArray , SArray > 입니다

리턴타입은   Array<double, A_Add<double,  A_Mult< double ,A_Scalar< double >,SArray> ,
   A_Mult< double , SArray , SArray > > >입니다

겁나 거대한 클래스가 만들어졌습니다
어떤 객체에 무슨 연산이 적용되었는지 기록 한 객체가 만들어 졌습니다
이제 실제 연산을 해봅시다
x = 1.2*x + x*y 

 Array의 할당연산자는 이렇게 구현되어 있었습니다

반복문을 돌면서 할당하고 있습니다
[]연산자를 사용하고 있네요 A_Add 에서는

 op1[idx] + op2[idx]
op1 은 A_Mult< double ,A_Scalar< double >,SArray>
op2 는 A_Mult< double , SArray , SArray >
[] 연산자를 사용합니다 A_Mult 에서는

이렇게 됩니다
Array의 할당 연산이 배열크기만큼 할당을 하며,
A_Add, A_Mult 의 [] 연산이 자신들이 저장하고 있는 배열의 계산을 해버립니다
실질적으로 이런연산이 됩니다

발표자료 올립니다
버전업 되었습니다



'Short Articles' 카테고리의 다른 글

Function Template  (0) 2012.03.31
음의 정수의 표현, 보수법  (1) 2012.02.27
C++ Template, Expression Templates #3  (0) 2012.02.21
C++ Template, Expression Templates #2  (0) 2012.02.17
C++ Basic Concept, Storage Duration  (0) 2012.02.10
:

C++ Template, Expression Templates #3

Short Articles 2012. 2. 21. 22:50
표현식 템플릿은 숫자 배열 클래스를 지원하기 위해 고안된 프로그램이 기술입니다
이번 아티클은 다음과 같이 진행합니다
1. 단순한 배열 클래스 구현하여 배열 연산에 대한 문제제기
2. 표현식 템플릿 구현
3. 표현식 템플릿을 아는 랩퍼클래스 구현
4. 실재 표현식 템플릿 사용해서 어떻게 동작하는 방법 추적

전체 표현식을 다 읽기 전에는 표현식의 일부만 계산하지 않고 전체 계산하기전에 어떤 객체에 무슨 연산이 적용되었는지 기록하는 것이 표현식 템플릿의 핵심입니다 

첫시간에 SArray 단순 배열 클래스를 만들었습니다
A_Add, A_Mult, A_Scalar에 대해서 배웠습니다
(스칼라 때문에 A_Traits 이라는 특질클래스도 배웠습니다)

이것을 가지고는 표현식 템플릿을 할 수 없습니다
이 표현식 템플릿을 알고 있는 랩퍼클래스 Array 만들어야 합니다

template <typename T, typename Rep = SArray<T> >
class Array;

Array가 값을 저장하는 실제 배열일 경우 SArray가 되며 A_Add나 A_Mult처럼 표현식을 나타낼 경우에는 중첩된 템플릿 식별자가 될 수도 있다

많은 연산들이 Rep 객체에 전달되기만 한다

이제 연산자를 구현해보자 이제부터 어려운 부분 시작입니다 정신을 똑바로 차리시고 코드에 집중해 주세요
두 배열의 덧셈입니다

복잡합니다 ㅠㅠ
템플릿
template <typename T, typename R1, typename R2>
T는 자료형이고요 R1, R2는 실제 배열클래스입니다 여기서는 SArray가 되겠죠?

리턴타입은 Array<T,A_Add<T,R1,R2> >
Array인데 자료형은 T이고 실재저장형은 A_Add<T,R1,R2> 인데
이것은 A_Add<T,R1,R2>은 R1,R2 저장한 결과 담고 있는 배열 이라고 생각해도 된다고 했죠
실재 저장한것이 아니라 R1과 R2 객체에 덧셈연산을 적용되었다고 기록하는 것입니다
앞서 말씀드렸지만 [] 연산자를 호출할때 그때 저장해서 값을 리턴합니다
하지만 여기서 수식이 복잡해지므로 우선 저장한 결과를 담은 배열이라고 생각합시다

함수명 operator+ 연산자 오버로딩 했습니다 C++ 기본 기능

함수인자
Array<T,R1> const& a
Array<T,R2> const& b
앞서 말씀드렸지만 R1, R2는 실제 저장 배열클래스입니다 여기서는 SArray 타입입니다
a는 자료형 T 실재배열 클래스 R1 값을 가지고 있는 레퍼클래스 Array의 객체 입니다
b도 마찬가지 입니다

리턴문 Array<T,A_Add<T,R1,R2> > (A_Add<T,R1,R2>(a.rep(),b.rep()));
가장 난해하면서 핵심 입니다
먼저 A_Add<> 객체를 생성 합니다
A_Add<T,R1,R2>(a.rep(),b.rep())
a.rep() 실재 저장된 배열 클래스를 반환하는 연산자 입니다
A_Add<T,R1,R2> 는 클래스 명이고요 
A_Add<T,R1,R2>(a.rep(),b.rep())은  A_Add<T,R1,R2>클래스의 생성자 호출 입니다
그 다음에 리턴 타입 객체를 생성합니다
Array<T,A_Add<T,R1,R2> > 은 클래스 명 입니다
Array<T,A_Add<T,R1,R2> > (A_Add<T,R1,R2>(a.rep(),b.rep()))은 클래스 생성자 호출 입니다
템플릿이 들어가서 한눈에 알아보기가 힘들지만 어쨌든 생성자를 호출해서 리턴 합니다
Array를 리턴타입으로 사용하는 이유는  Array객체로 래핑해 배열의 데이터를 나타내는  다른 객체와 같이 사용할 수 있게 하는 것입니다
리턴된  Array<T,A_Add<T,R1,R2> > 객체가 다른 Array객체와  operator+ 연산이 가능해 집니다

다음은 배열 곱셈연산입니다

배열 덧셈연산과 동일한 과정을 거치므로 설명을 생략합니다
다음은 스칼라와 배열 곱셈 입니다

자~ 설명 들어갑니다 
템플릿
 template <typename T, typename R2>
T는 자료형, R2는 실재 저장 배열 클래스 여기서는 SArray 입니다

리턴타입 Array<T, A_Mult<T,A_Scalar<T>,R2> >
Array 인데 T는 자료형  A_Mult<T,A_Scalar<T>,R2> 저장배열
A_Mult<T,A_Scalar<T>,R2>는 A_Scalar<T>와 R2를 곱한 결과를 담는 배열
A_Scalar<T> 는 모두 같은 값이 배열 이고요

함수명 operator* 연산자 오버로딩

함수인자
T const& s 평범한 값
Array<T,R2> const& b R2를 실재 저장클래스로 갖고 있는 레퍼배열 클래스

리턴값 Array<T,A_Mult<T,A_Scalar<T>,R2> > (A_Mult<T,A_Scalar<T>,R2>(A_Scalar<T>(s), b.rep()));
먼저 s를 스칼라로 변경합니다
A_Scalar<T>(s) 스칼라 생성자 호출
두 배열을 곱셈 합니다
A_Mult<T,A_Scalar<T>,R2> 클래스 형
A_Mult<T,A_Scalar<T>,R2>(A_Scalar<T>(s), b.rep() ) 생성자 호출
리턴타입  Array<T,A_Mult<T,A_Scalar<T>,R2> >  
Array<T,A_Mult<T,A_Scalar<T>,R2> > (A_Mult<T,A_Scalar<T>,R2>(A_Scalar<T>(s), b.rep()));  생성자 호출
리턴된 Array<T,A_Mult<T,A_Scalar<T>,R2> > 객체는 다른 Array객체와 연산이 가능해 집니다

다음번은 실재 값을 사용해서 효율적인지 확인 해보겠습니다
 
:

C++ Template, Expression Templates #2

Short Articles 2012. 2. 17. 20:14
표현식 템플릿은 숫자 배열 클래스를 지원하기 위해 고안된 프로그램이 기술입니다
이번 아티클은 다음과 같이 진행합니다
1. 단순한 배열 클래스 구현하여 배열 연산에 대한 문제제기
2. 표현식 템플릿 구현
3. 표현식 템플릿을 아는 랩퍼클래스 구현
4. 실재 표현식 템플릿 사용해서 어떻게 동작하는 방법 추적

우리가 실질적으로 해야 하는 배열 연산입니다
배열을 어떻게 효율적으로 연산을 할까요?

이번에 사용되는 표현식을 살펴봅시다  1.2*x + x*y 
연산트리
연산트리로 표현하였습니다
여기에서 X,Y가 배열 클래스 입니다
1.2는 스칼라를 나타내는 클래스로 변경되고요
+,* 는 바로 표현식 템플릿이 되는 겁니다

전체 표현식을 다 읽기 전에는 표현식의 일부만
계산하지 않고 전체 계산하기전에 어떤 객체에
무슨 연산이 적용되었는지 기록하는 것

표현식 템플릿의 핵심입니다

 이 트리를 전위순회로 변경하면 다음과 같습니다




   이 트리를 전위순회로 변경하면 다음과 같습니다  


+, *, 1.2 가 클래스 템플릿으로 변경하고 주어진 표현식을 다음과 같은 데이터형을 가지는 객체로 바꿔봅시다

A_Add<  A_Mult<A_Scalar<double>, Array<double> >,
    A_Mult<Array<double>, Array<double> > >
새로운 배열 Array 클래스 템플릿과 A_Scalar, A_Add, A_Mult 와 함께 사용되었습니다

이제 본격적으로 알아봅시다
먼저 덧셈을 나타내는 A_Add 클래스입니다


여기서 중요한 것은 A_Add클래스는 배열의 덧셈연산을 나타내지만
실재 덧셈 연산을 하지 않습니다
다시 한번 언급하면 표현식 템플릿의 핵심 기술,  어떤 객체에 무슨 연산이 적용되었는지 기록하는 것 입니다
중요하니까 계속 반복할게요
여기 A_Add 클래스는 두 피연산자를 저장하고 덧셈 연산을 기록합니다
배열 참조 연산자에서 [] 덧셈을 기록하는 것입니다
두 피연산자를 저장했다가 A_Add 배열처럼 [] 접근할때 덧셈 연산을 한 결과를 제공합니다

그 다음은 곱셈을 나타내는 A_Mult 클래스 입니다 

곱셈도 마찬가지 입니다
다시 한번 언급하면 표현식 템플릿의 핵심 기술,  어떤 객체에
무슨 연산이 적용되었는지 기록하는 것 입니다
여기 A_Mult 클래스는 두 피연산자를 저장하고 곱셈 연산을 기록합니다
배열 참조 연산자에서 [] 곱셈을 기록하는 것입니다 
 다음을 스칼라를 나타내는 A_Scalar 클래스입니다

스칼라는 모든 인덱스에 대해 같은 값을 가지고 있는 배열과 같으므로 배열 참조 연산자 []에서는 모두 같은 값을 반환 합니다

도우미 클래스 A_Traits 클래스
피연산자를 정의할 때 이렇게 정의를 했습니다
typename A_Traits<OP1>::ExprRef op1;    // first operand
typename A_Traits<OP2>::ExprRef op2;    // second operand
최종 연산이 이루어지기 전까지 어떤 객체에 무슨 연산이 적용되었는지 기록하는 것
표현식 템플릿의 핵심입니다
대부분의 임시 노드들은 최상위 표현식과 관련이 있기에 전체 표현식 까지 살아 남아야 합니다
A_Scalar 노드는 예외 입니다
연산자 함수에 연결되며 전체 표현식의 계산이 종료 전에 사라집니다
(이게 왜그런지는 고민을 해보세요 그리고 저한테도 알려주세요 저도 잘 몰라서요) 
스칼리 피연산자는 값으로 복사돼야만 합니다

A_Traits 클래스 특질 클래스로 스칼라 처리를 하였습니다
A_Scalar, A_Add, A_Mult 이 세 클래스로 통해 표현식 템플릿을 표현합니다
앞으로 알아보기 힘들 정도로 템플릿의 향연을 보실 겁니다
그전에  짚고 넘어가겠습니다

A_Add는 두 피연산자를 저장하고 덧셈연산을 기록
A_Mult는 두 피연산자를 저장하고 곱셈연산을 기록
A_Scalar는 스칼라 값을 배열처럼 처리하는 것

템플릿 안에 템플릿이 가능하듯이 또는 곱셈 후에 덧셈, 덧셈 후에 곱셈... 연산후에 연산 하듯이 사용이 가능합니다
말을 복잡하게 썻네요 즉  A_Scalar, A_Add, A_Mult는 또 다른  A_Add, A_Mult의 피연산자로 가능합니다
그럴때는

A_Add 두 배열을 덧셈을 저장한 배열
A_Mult 두 배열을 곱셈을 저장한 배열 
A_Scalar 모두 같은 값을 같고 있는 배열
라고  판단하셔도 무관합니다
어짜피 시작을 배열연산에 발생하는 임시 변수의 비효율 때문에 템플릿 표현식을 언급했거든요 

너무 길어 졌네요
다음에는  실제 저장소를 제어하고 표현식 템플릿을 알고 있는 Array 형 클래스를 만들겠습니다
:

C++ Basic Concept, Storage Duration

Short Articles 2012. 2. 10. 12:21
Sotrage duration 이란 object 에 대해서 object 를 포함하고 있는 storage 의 최소 유효 생명 주기를
정의하는 속성 입니다. Storage duration 는 다음과 같은 것들이 있습니다.
  • Static storage duration
  • Thread storage duration
  • Automatic storage duration
  • Dynamic storage duration 

작성중...
 
 
:

C++ Template, Expression Templates #1

Short Articles 2012. 2. 8. 16:50
표현식 템플릿은 숫자 배열 클래스를 지원하기 위해 고안된 프로그램이 기술입니다
이번 아티클은 다음과 같이 진행합니다
1. 단순한 배열 클래스 구현하여 배열 연산에 대한 문제제기
2. 표현식 템플릿 구현
3. 표현식 템플릿을 아는 랩퍼클래스 구현
4. 실재 표현식 템플릿 사용해서 어떻게 동작하는 방법 추적


배열 클래스를 구현해서 이런 계산을 해봅시다
단순한 배열 클래스 입니다 

단순한 배열을 클래스로 구현하였습니다
산술연산자는 다음과 같이 구현합니다
자 배열 클래스와 연산자를 구현하였습니다
배열 계산을 해봅시다
코드상 배열을 클래스로 구현했다고 생각할 수 있습니다
그러나 이런 구현은 두가지 이유때문에 비효울적으로 알려져 있습니다
1. 연산자의 모든 응용은 적어도 하나의 임시 배열을 생성한다
2. 연산자의 모든 응용은 인자와 결과 배열에 대해 부가적으로 탐색한다 

산술 배열 라이브러리의 초기 구현에서는 사용자들이 계산 할당자(+=,*=) 사용해 임시배열을
줄이게 권유했다고 합니다


이런 연산자를 사용하면 다음과 같이 수정할 수 있네요
표기 방식이 이상하고 여전히 tmp 배열이 필요하고
루프로 인해  메모리 읽기 대략 6000회, 쓰기 대략 4000회 사용합니다

우리가 원하는 실질적인 계산은 바로 이것입니다

배열을 어떻게 효율적으로 연산을 할까요? 

'Short Articles' 카테고리의 다른 글

C++ Template, Expression Templates #2  (0) 2012.02.17
C++ Basic Concept, Storage Duration  (0) 2012.02.10
C++ Basic Concept, One definition rule (ODR)  (2) 2012.02.07
C++11, Lambda Expressions #2  (0) 2012.02.01
C++11, Lambda Expressions #1  (2) 2012.01.30
:

C++ Basic Concept, One definition rule (ODR)

Short Articles 2012. 2. 7. 14:57
(이 글은 C++ Templates the Complete Guide 부록의 내용을 바탕으로 작성되었습니다.)

C++ , ODR 에서 어떤 변수, 함수, 클래스 형, 열거 형 또는 템플릿도 번역 단위 내에서
딱 한 번만 정의 되어야 한다고 규정하고 있습니다.

+번역단위
번역 단위는 #define 매크로 치환등의 전처리 적용 이후 컴파일러에게 전달되는 코드의 덩어리를 지칭합니다.
컴파일러가 하나의 object 를 생성해내는데 참조하게 되는 코드 범위를 가리킨다고 볼 수 있고요.
따라서 파일 단위와는 차이가 있습니다. 

예를 하나 들어 보겠습니다.

a.h
a.cpp
main.cpp
이렇게 3개의 파일이 있다고 했을 때, 컴파일러는 a.cpp , main.cpp 두 소스 파일에 대해서 각각
a.obj , main.obj (g++ 이라면 a.o , main.o) 라는 오브젝트 파일을 생성합니다.
이 때 컴파일러에 전달되는 것은 '#include '로 포함된 파일의 내용이 추가된 코드 덩어리 입니다.

컴파일러는 이렇게 각 각의 코드 덩어리를 해석하기 때문에
foo() 함수의 정의는 a.obj 에 기록 되지만 main.obj 에는 foo() 함수의 구현을 모릅니다.
main.obj 는 단지 foo() 함수의 symbol 정보만을 들고 있습니다.
이것은 linking 과정에서 linker 에 의해 해석되어 구현 코드와 연결되게 됩니다.

ms윈도우에서 vs 기반으로 작업을 하시는 분들 중에 이런식의 컴파일/링킹 과정을 
분리해서 생각 하는 것에 생소한 분들이 좀 있는 것 같습니다. 
a.cpp 파일이 없더라도 컴파일 과정은 문제 없이 수행됩니다.

컴파일러가 cl.exe 라면 /c 옵션을 주어 컴파일 과정만을 수행할 수 있습니다.




아무튼 위에서의 foo() 함수 같은 경우에 external linkage 를 갖는다고 합니다. 반대로 같은 번역 단위에
존재할 경우에는 internal linkage 를 갖는다고 하죠.

다시 ODR 에 대한 이야기로 돌아가서..

+ ODR 에 따라 프로그램에서 단 한번만 정의 되어야하는 것에는 다음과 같은 것들이 있습니다.
    • 인라인이 아닌 함수/인라인이 아닌 멤버 함수
    • external linkage 를 갖는 정적 데이터 멤버
    • 인라인이 아닌 (함수 템플릿/멤버 함수 템플릿/클래스 템플릿 멤버) 가 export 와 함께 선언된 경우
    • 클래스 템플릿의 정적 데이터 멤버가 export 로 선언된 경우 
이 것들은 external linkage 를 갖는 사항들로 internal linkage 를 갖는 것들에 대해서는 적용되지 않습니다.
(번역단위 내에 선언된 static 변수,  anonymous namespace 등은 internal linkage 를 갖습니다.)

프로그램 내에서 어떤 실체에 대해 사용(명시적이든 묵시적이든 참조를 하는)이 있을 경우,
이 실체는 프로그램 내에 하나만 존재 해야 합니다. 
이 규칙에 대해 (sizeof , typeid) 사용이 좀 예외적일 수가 있는데
이 둘의 연산자의 일부로써 실체에 대한 참조가 일어날 경우 기본적으로는 실체가 사용되었다고 보지 않지만
typeid 연산자의 인자가 다형적 객체(상속, 가상 함수를 포함)를 가리키는 경우에는 사용되었다고 판단합니다.


+ 번역 단위 내에서 실체는 한 번 이상 정의 될 수 없습니다.
구조체/공용체를 포함한 클래스 타입은 번역 단위 내에서 다음과 같은 사용 사항들에 대해
정의돼 있어야 합니다.
  • 객체의 생성(포함관계 등으로 인한 간접 생성을 포함)
  • 데이터 멤버의 선언 
  • 객체에 대한 sizeof / typeid 연산자
  • 멤버에 대한 (명시적/암시적) 접근
  • 임의의 어떤 변환을 사용한 표현식 - 클래스 타입 상호간 변환
  • 암시적 형변환, static_cast, dynamic_cast 를 사용한 표현식 - (void*를 제외한)클래스 포인터(또는 참조) 상호간 변환
  • 값의 할당
  • (인자나 리턴 타입을 포함)함수 정의 또는 호출, 그러나 선언만의 경우 정의될 필요 없음.
 
이 규칙은 클래스 템플릿을 통해 생성되는 클래스 타입에 대해서도 적용됩니다.
즉, 클래스 타입을 인스턴싱 시키는 클래스 템플릿은 위와 같은 상황에 대해 정의되어 있어야 합니다.

인라인 함수들의 경우에는 인라인 함수가 사용되는 각각의 번역 단위에 정의가 있어야 합니다.
인라인은 코드 치환이므로 심볼만을 인식하고 있는 경우 코드 정의를 치환할 수 없습니다.
 
+ 교차 번역 단위에서의 동등성 제약
이 부분은 설명 생략하겠습니다.
참고적으로, MS 의 c++ 컴파일러인 cl.exe 는 다중 정의 자체를 허용 하지 않습니다.
관련해서 검색해보시고 테스트 해보실 분은 g++ 을 이용하여 테스트 해보시기 바랍니다.


 

'Short Articles' 카테고리의 다른 글

C++ Template, Expression Templates #2  (0) 2012.02.17
C++ Basic Concept, Storage Duration  (0) 2012.02.10
C++ Template, Expression Templates #1  (3) 2012.02.08
C++11, Lambda Expressions #2  (0) 2012.02.01
C++11, Lambda Expressions #1  (2) 2012.01.30
: