g ++和clang ++使用`va_arg()`和variadic模板包扩展

时间:2017-02-18 18:32:27

标签: c++ c++11 templates variadic-templates variadic-functions

尝试回复another question,为了好玩,我编写了以下愚蠢的程序,尝试使用新的C ++样式的可变参数模板参数列表转换旧的C风格的可变参数函数参数列表(也在wandbox

#include <cstdarg>
#include <iostream>
#include <stdexcept>

template <typename ... Args>
void bar (Args const & ... args)
 { 
   using unused = int[];

   (void)unused { (std::cout << args << ", ", 0)... };

   std::cout << std::endl;
 }

template <typename ... Ts>
void foo (int num, ...)
 {
   if ( num != sizeof...(Ts) )
      throw std::runtime_error("!");

   va_list args;                     

   va_start(args, num);           

   bar( va_arg(args, Ts)... );

   va_end(args);
 }

int main ()
 {
   foo<int, long, long long>(3, 1, 2L, 3LL); // print 1, 2, 3, 
 }

但是clang ++并且没有问题地执行它,g ++给出了以下错误

prog.cc: In function 'void foo(int, ...)':
prog.cc:26:25: error: expansion pattern 'va_arg(args, Ts)' contains no argument packs
    bar( va_arg(args, Ts)... );
                         ^~~
像往常一样:谁是对的? g ++或clang ++?

附录

更改行

 bar( va_arg(args, Ts)... );

in

 bar( ((void)Ts{}, va_arg(args, Ts))... );

程序由两个编译器编译,但执行它,clang ++版本打印

1, 2, 3,
当g ++版本恢复值并打印

时,

(如所预期的那样)

3, 2, 1,

0 个答案:

没有答案