variadic_arguments — 가변 인자

variadic_arguments — 가변 인자 (Variadic arguments)

**가변 인자(variadic arguments)**는 함수가 임의 개수의 추가 인자를 받을 수 있게 해주는 기능이에요.

함수의 매개변수 목록에서 마지막 매개변수가 줄임표(...)인 함수가 가변 함수(variadic function)예요.

출처: cppreference

본문

int printf(const char* format, ...);   // 가변 인자 함수
double sum(int count, ...);            // count 다음에 임의 개수

C++26부터 줄임표 앞의 콤마는 생략할 수 있게 됐어요 (deprecated된 표기는 콤마 필수).

이것은 함수 매개변수 팩(parameter pack) 확장과는 다르다는 점이 중요해요. 매개변수 팩 확장은 매개변수 선언자의 일부인 줄임표로 표시되지만, 가변 줄임표는 단독 매개변수예요. 둘 다 함수 템플릿 선언에 나타날 수 있어요.

template<typename... Ts>
void f(Ts...);      // 매개변수 팩 확장 — 타입 안전

void g(int, ...);   // 가변 인자 — C 호환 (타입 안전하지 않음)

가변 인자에 접근하려면 <cstdarg>의 매크로를 사용해요.

#include <cstdarg>
#include <cstdio>

double average(int count, ...) {
    va_list args;
    va_start(args, count);
    double sum = 0;
    for (int i = 0; i < count; ++i)
        sum += va_arg(args, double);
    va_end(args);
    return sum / count;
}

average(3, 1.0, 2.0, 3.0);   // 2.0

주의할 점들:

  • 가변 인자는 타입 안전하지 않아요. va_arg로 읽는 타입이 실제 전달된 타입과 달라도 검사되지 않고, 잘못 쓰면 정의되지 않은 동작이 돼요.
  • va_start, va_arg, va_end, va_copy 매크로는 <cstdarg>(C의 <stdarg.h>)에 있어요.
  • C++에서는 템플릿 매개변수 팩(가변 인자 템플릿)이 타입 안전한 대안을 제공해요. 가변 함수는 주로 C 호환 API(예: printf)를 다룰 때 사용해요.
// 타입 안전한 대안: 가변 인자 템플릿
template<typename... Args>
void print(Args&&... args) {
    (std::cout << ... << args);   // C++17 폴드 표현식
}

가변 인자는 오래된 C 스타일 함수(특히 printf 계열)와의 호환 때문에 여전히 필요하지만, 새 코드에서는 가변 인자 템플릿을 우선 사용하는 것이 안전해요.

더 알아보기 (Learn more)

cppreference