본문 바로가기

c++

[c++] __VA_ARGS__, parameter pack

 

공부를 하는 입장이기 때문에, 내용에 오류가 있을 수 있습니다. 오류가 있다면 적극적으로 알려주시면 감사합니다!

 

Variadic 매크로

 Variadic 매크로는 __VA_ARGS__라는 식별자를 사용하며, 매크로 함수에서 가변인자를 받는 기능을 한다. 사용방법은 매우 간단한데, 입력받는 변수에 '...'(parameter pack)을 사용하고 실행하는 변수 부분에 __VA_ARGS__를 사용하면 된다. 

 

#define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }

int main() {
    CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n");
    CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n"); 
    
    ......

 

 예시를 보면  CHECK1이라는 매크로 함수에 x인자와 ...을 받는데, main함수에서 보면 인수가 매우 많은 것을 확인할 수 있다. CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n"); 에서 x는 0이 되는 것이고 그 뒤에 인자들은 __VA_ARGS__에 치환되어 printf("here %s %s %s", "are", "some", "varargs1(1)\n")로 된다.'

 

Parameter pack

 parameter pack이란 0개 이상의 함수 인수를 허용하는 함수 매개변수이다. '...'을 이용하여 사용할수 있다. 함수나 tempelet 뿐만 아니라 size of, lamda등등 다양한 곳에서 사용한다.

 

  tempelet과 function의 경우는 가변 인자를 표현하는 인자 앞에 표시한다.

template < typename ... Ts > 
void func ( Ts... args ) 
{ 
    const  int size = sizeof... ( args )  +  2 ; 
    int res [ 크기 ]  =  { 1 , 인수..., 2 } ; // 초기화 목록은 순서 지정을 보장하므로 
 
    // 팩의 각 요소에 대해 // 순서대로 함수를 호출하는 데 사용할 수 있습니다 . 
    int dummy [ sizeof... ( Ts ) ] = { ( std:: cout << args, 0 ) ... } ; }

 

 이건 reference에 있는 예제 인데, template < typename ... Ts >처럼 가변 인자의 자료형을 표현하는 Ts앞에 '...'을 표시한다. 함수 또한 Ts... args 가변인자의 이름인 args앞에 '...'을 표시한다. 만약 특정 인자를 추가하고 싶다면 '...' 앞에 표시한다.

template < typename T,  typename U, typename ... Ts > 이런식으로 함수 또한 사용한다.

 

#define __RCLCPP_MAKE_SHARED_DEFINITION(...) \
  template<typename ... Args> \
  static std::shared_ptr<__VA_ARGS__> make_shared(Args && ... args) \
  { \
    return std::make_shared<__VA_ARGS__>(std::forward<Args>(args) ...); \
  }

 

 이건 rclcpp라는 라이브러리에 있는 매크로 함수인데, 이 코드를 해석하기 위하여 이 내용들을 공부했기 때문에 좋은 예시가 될 것 같다. (Args && ... args와 std::forward<Args>(args) ...는 parameter pack문법과 perfect forwarding문법이 합쳐진 것인데 perfect forwarding는 여기서는 설명하지 않도록 하겠다.)

'c++' 카테고리의 다른 글

[c++] visibility  (0) 2024.05.02
[c++] 복사 생성자와 복사 대입 연산자  (1) 2024.04.29
[c++] Range-based for loop (범위 기반 for 문)  (1) 2024.04.25
04. C++만의 특징 2  (0) 2024.01.14
03. C언어 복습  (0) 2024.01.04