WinAPI

키 입력, template 가변인자

Nin 2021. 1. 30. 17:42

키 입력의 상태는 4가지의 경우로 볼 수 있다.

처음 눌렸다.

누르고 있다.

지금 땟다.

안누르고 있다.


특정 키를 만들어 낼 수 있고 멀티키 입력으로도 만들어 낼 수 있다.

#include <string>

void CreateKey(const std::string& _KeyName, int _Key)

위와 같이 키를 만들어 내는 함수를 만들수 있는데

위의 함수는 하나의 키 입력으로 밖에 만들 수 없다.

CreateKey("LeftMove" , 'a') 이런식으로는 가능하지만

CreateKey("Attact" , 'q' , 'e') 이렇게 q와e가 눌리면 공격하는키는

만들어 낼 수가 없다.그렇다고 인자를 하나 늘린다면

2개의 키조합까지만 가능한 함수가 된다.그래서 가변인자를 사용할 수 있다.

가변인자를 사용할 경우 인자의 갯수를 알 수 없다.

그래서 template 가변인자를 사용한다.

void Test(int _a,int _b,int _c)
{
 
}

template<typename ... REST>
void Func(REST ... _Arg)
{
   Test(_Arg...);
}

템플릿 가변인자는 위와 같이 사용 할수 있고

int main()
{
   Func(1,2,3);
}

실제 사용하는 것을 보면 일반 가변인자와 똑같다.

그치만 동작 원리는 아래와 같다.

void Func(int _a,int _b,int _c)
{
   Test(_a,_b,_c);
}

이러한 함수를 만들어 낸다.이렇게 Test(_Arg...)같은 경우를 

인자를 확장한다고 말한다.

지금 Func함수의 테스트에서 _Arg...만 이용할 수 있지 첫번째 인자만,

두번째 인자만 이런식으로는 사용이 불가능하다.

Func(1 , 'c' , 1.0f) 이렇게 넣어주면은 각 int,char,float형을 가지고있고

이를 각 인자로만 처리하고 싶다면 int형 인자를 받는 함수,char형을 인자로 받는 함수

float형을 인자로 받는 함수를 만들어주면 된다.여기서 또 template 문법을 사용한다.

template<typename T>
void Test(T _Value)
{

}

template<typename ... REST>
void Func(REST ... _Arg)
{
   Test(_Arg...);
}

int main()
{
   Func(1 , 'c' , 1.0f);
}

이렇게 하면 될거같지만 인수가 1개 있어야 하는데 3개를 사용했다는 문구와 함께

컴파일 에러가 난다.Func함수에 들어온 인자는 결국 3개인데 Test는 1개의 인자만을

받기때문이다.그래서 Test함수에 다시 또 template 가변인자를 사용한다.

template<typename T , typename ...REST>
void Test(T _Value,REST ... _Arg)
{
   Test(_Arg...);
}

또 템플릿 가변인자를 사용하고 재귀함수를 이용한다.그치만 위의 함수에서 

조건을 보면 최소한 1개의 인자는 들어와야 한다.그렇기 때문에 오버로딩을 이용하여

template<typename T>
void Test(T _Value)
{

}

이렇게 한개의 인자를 받는 함수도 만들어 줘야 한다.

실행 원리를 정리해보면 Func함수가 호출되면서

템플릿이 int,char,float 을 처리하는 함수를 만든다.

그러고 나서 Test함수도 int,char,float 을 처리하는 함수를 만든다.

T 에는 int형이 들어가고 Rest에는 char,float이 들어간다.

void Test(int _Value,char,float)
{
   Test(char,float);
}

이렇게 생각할 수 있다.재귀 함수가 호출 될때는 T는 빠지고 _Arg...만 들어가기 때문에

int형은 빠지게 된다.그렇기 때문에 재귀 함수로 다시 char,float로 호출되고

이번에는 char형이 T로 들어가기 때문에 다음 재귀함수 호출시 float만 들어가게 된다.

이런식으로 template이 알아서 다 만들어 준다.