라벨이 generic programming인 게시물 표시

[C++] Variadic template

전통적인 C나 C++에서 잘못 쓰면 위험한 것 중 하나로 stdarg가 있었다. 이를 이용하면 임의의 개수의 인자를 받는 variadic function을 만들 수 있지만, 함수의 시그니쳐를 통한 타입 체크를 완전히 무시하기 때문에, 함수의 호출자가 규약을 지키지 않고 함수를 사용하더라도 컴파일 타임에 문제를 잡을 수 없기 때문에 실행 시에 여러 가지 문제가 발생했다. 이런 문제를 피하고자 stdarg를 사용하지 않고, 예상되는 인자의 최대 개수를 예상해서 받는 인자의 개수가 다른 함수를 오버로딩하여 사용하는 경우가 더 많았다. C++11에서는 variadic function을 타입 시스템과 붙여 컴파일 시간에 타입 체크 할 수 있게 하려고 variadic template이라는 문법을 추가하였다. Variadic template을 사용하면 사용된 인자의 타입 별로 instantiation 되기 때문에 바이너리의 크기는 커지지만, 컴파일 타임에 타입 체크를 할 수 있으며 실행 시에 생기는 비용을 줄여준다. Variadic template이 될 템플릿 인자는 ellipsis(...)를 붙여 다음과 같이 사용한다.  Variadic template을 사용하는 패턴은 크게 2가지이다. 첫 번째는 다른 함수로 인자를 전달하는 것이다. 대표적으로 make_unique가 이런 경우에 속한다. Possible implementation에서 볼 수 있듯이 make_unique는 std::forward(args)...를 이용해 T 타입의 생성자에게 모든 인자를 전달한다. 여기서 std::forward 함수 호출 뒤에 ellipsis가 붙어있다는 것이 중요하다. 이를 pack expansion이라고 하는데 std::forward 함수에 인자를 넘기는 패턴을 variadic arguments인 args에 전부 적용하는 것이다. 따라서 args가 N 개의 인자였으면 번의 std::forward 함수가 불리게 된다. 이때 단순히 전달하는 것이 아니라 값을 수정해서 다른 함수로 …