C++을 포함한 객체지향 언어들은 입출력 개념을 Stream 형태로 구현하였습니다.

가장 많이 쓰이는 Stream 구현체는 보통 IOStream이나 FileStream, StringStream 정도인데요, C에서 입출력을 할 때 printf, scanf처럼 format 형식으로 여러 변수를 다루다가 입출력 연산자인 >>나 << 를 줄줄이 써가면서 입출력 결과물의 형태를 맞추게 되면 꽤 귀찮습니다.

그나마 C#이나 Java는 Stream계열 클래스에 [Format()함수]를 구현하거나 [문자열 보간] 같은 갓갓기능을 추가해서 편한데요, C++은 모던 C++에서도 이런 부분이 구현되어 있지 않습니다.

이 글은 C++11에 추가된 가변 인자 템플릿(Variadic Template)을 이용해 Format 과 비슷하게 여러 변수를 받아 합친 std::string을 반환하는 함수를 만들어 볼 것입니다.

[main.h]

[main.cpp]

간단하게 구현해본 결과입니다.

위와 같이 구현하면, stringstream을 제외하고 2개 이상의 인자가 있을 때는 return 을 통해 후자의 strFormat이 계속 호출되다가 stringstream을 제외하고 하나의 인자가 있을 때 비로소 전자의 strFormat이 호출되게 됩니다. 그 후 결과물이 맨 처음 return까지 전달되는 것이죠.

 

핵심 부분은 후자의 함수를 정의할 때 typename … Tn 처럼 Ellipse Operator ““을 이용해 여러 개의 typename들이 있다는 걸 명시하는 것과,

재귀를 시키는 부분에서 마지막 인자를 paramN… 처럼 …을 이용해 여러 개의 typename을 그대로 전달하는 것입니다.

 

지금 언급했지만 재귀함수 같은 느낌으로 여러 개의 인자가 있을 때의 함수 템플릿하나의 인자가 있을 때의 함수 템플릿을 정의해주면 됩니다.

여기서 여러 개는 0개도 포함하는 것이기 때문에, 최소한 하나 이상은 꼭 있게 하려면 위 코드처럼 첫 번째 템플릿 인자(예시에선 T0)를 인자목록에 명시해주면 됩니다.

또 위 코드에선 stringstream 객체가 꼭 있어야 해서 가변 인자 앞에 해당 객체를 받는 인자를 적어뒀지만, 이런 경우가 아니라면 없어도 상관 없습니다.

여기선 반환값이 있는 함수 템플릿을 만들었지만 반환값 자체는 없어도 됩니다.  또 함수 뿐만 아니라 클래스에 대해서도 가변 인자 템플릿을 정의할 수 있습니다. 자세한 정보는 [MS 문서]를 참고하세요.

 

귀찮아서 만들긴 했지만, 사실 C++의 stringstream 자체가 꽤 느립니다. 따라서 위와 같은 함수도 그렇고 stringstream도 그렇고 비교적 짧은 길이의 std::string을 다룰 때나 쓸만하지 텍스트 파일을 읽어들인다거나 엄청 긴 문자열을 만들어내는 경우엔 그냥 원시 문자열(char*)과 C 계열 함수(cstring, cstdio 등)를 이용하는게 낫습니다. 아니면 오픈소스로 있는 format 라이브러리들이 좀 있으니 이걸 쓰는것도 좋구요.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.