우리는 함수선언의 문법을

return_type function_name( arguments... )

{

    // to do

}


이렇게 알아 왔다.


function_name 이란 이름의 함수는

괄호 안에 선언된 형식의 인자들을 이용해서 함수 내부에서 세부 조작이 가능하게 해 준다.

( 어떤 동작의 주어, 목적어, 수식어 중 무엇이 올 수도 있다 )



template 문법에서는

기존의 함수 선언에서 반드시 구체화 해야했던 [1. 타입]과 [2. 리터럴 상수]에 대해서도

자리만 잡아 놓고 표현할 수 있다.


유념 해야할 것은, 템플릿 확장 문법에 변수는 사용할 수 없다.

컴파일 타임 ( constant time ) 에 결정되어야 하기 때문이다.

그러니, 왜 템플릿 파라메터로 변수를 못넘김? 하고 울지마라. 바랄걸 바라야지.


이미 다 구체화된 일반 함수와 달리,

템플릿 함수는 실제 사용될 때, 사용된 예를 근거로 컴파일러가 알아서 치환해 준다.


template< 자리만 잡아 둘 인자들 >

return_type function_name( arguments... )

{

   // to do

}


처럼 표현된다.



템플릿 내부에 사용될 [1. 타입]의 경우,


    1. typename

    2. class


    둘 중 하나의 키워드를 사용해 [임의의 타입]임을 알려야 한다. 둘 중 어느걸 써도 무방하다.

    일단 난 줄맞추는걸 좋아해서 짧은걸 선호하게 되다 보니 class 를 쓰겠다.


    template< class R, class T > // R 과 T 는 걍 타입입니다. int 고 double 이고 사용자 정의 구조체건 간에 말이쥬. 란 뜻

    R function_name( T argument1 )

    {

        // to do

    }


    처럼 표현할 수 있다는 이야기.


    위의 경우는 T 라는 타입이 function_name 을 실제 사용할 때 전달해주는 첫 번째 인자에 의해 컴파일러가 추론할 수 있다.

    하지만 리턴 타입으로 쓰인 R을 추론할 수 없기 때문에,


    fuction_name< void >( 0 );


    처럼 사용해 주면,


    void function_name( int argument1 )

    {

        // to do

    } 


    라는 함수를 컴파일러가 자동으로 만들어 준다는 것이다.


    이전 시간에 설명했지만 환기시켜주자면 c++컴파일러는 인자에 의한 다형성을 지원하기 때문에 사실상,


    void function_name_int( int argument1 )

    {

        // to do

    }


    을 만들어준 셈이지.



템플릿 내부에 사용될 [2. 리터럴 상수]의 경우,


    1. null_ptr

    2. 부동소수점 숫자

    3. 리터럴 문자열


    을 제외한 순수 상수 표현을 사용할 수 있다.


    template< int LEVEL > // int 라고 했지만 이것은 리터럴( 말 그대로 ) 상수다.

    void game_start()     // const int a = 변수; 처럼 사용된 임시 고정 상수가 아니란 말.

    {

        // game loop

    }


    처럼 표현될 수 있다는 이야기.


    이경우, 사용할 때 LEVEL 에 해당하는 템플릿 인자를 넘겨 줘야 한다.


    game_start< 5 >();


    처럼 쓰면 된다.



요약하면,

템플릿 함수를 선언하기 위해 ( 템플릿 구조체나 템플릿 클래스도 마찬가지 )

기존의 함수 선언이나 구조체, 클래스 선언 앞에 template< ... > 표현을 넣어주면 된다. 간단!

그리고 템플릿으로 선언된 함수나 클래스를 호출하기 위해 필요한 템플릿 파라메터를 함수명이나 클래스명 뒤에 붙여주면 된다.

function_name< ... >( ... );

처럼 간단!


즉, 템플릿 함수 호출에 있어서

< ... > 는 컴파일 타임에 컴파일러로 하여금 코드 생성에 사용하도록 전달될 인자들,

( ... ) 는 런타임에 전달될 인자들을 의미한다고 해석하면 된다.


그러므로, 우리가 template 문법이 없던 시절


void game_start1()

{

    const int LEVEL = 1;

    ...

}


void game_start2()

{

    const int LEVEL = 2;

    ...

}


void game_start3()

{

    const int LEVEL = 3;

    ...

}


처럼 구현 하던 것을,


template< int LEVEL >

void game_start()

{

    ...

}


하나로 구현할 수 있게 되었고, 사용될때 알아서 game_start1, game_start2 ...

얼마든지 만들어진다. 라고 생각하면 된다는 것!


개편함!


템플릿도 결국 함수의 다형성 처럼 이름이 다른 함수를 자동으로 만들어준다고 생각하면 된다.

function_name< ... > 까지가 이름인것이쥐.

내부적으론 functon_name_types..._constants... 처럼 이름이 만들어진다고 생각하면 되고 말야.