在模板中使用变量参数列表

时间:2013-04-29 16:04:47

标签: c++ variadic-functions

我一直试图在下面的代码中找出我所面临的问题。

#include <iostream>
#include <stdarg.h>
#include <vector>
using namespace std;

template <typename T>
class C {
        vector<T> vec;
    public:
        void PrintValues(int size, T val, ...){
            va_list v;
            va_start(v,val);
            for ( int i = 0 ; i < size ; i++ ) {
                T p = va_arg(v,T);
                vec.push_back(p);
                cout<<p<<" ";
            }
            va_end(v);
        }       
};

int main() {
    C<int> a;
    C<char *> b;
    cout<<endl;
    a.PrintValues(10,1,4,6,2,8,5,3,7,10,9);
    cout<<endl;
    b.PrintValues(10,"a","b","c","d","e","f","g","h","i","j");
    cout<<endl;
    return 0;
}

我使用g ++ 4.4.3在我的Ubuntu 10.04桌面上编译了这段代码。

使用以下警告编译的代码

testcode.cpp: In function ‘int main()’:
testcode.cpp:25: warning: deprecated conversion from string constant to ‘char*’

虽然我期待像

这样的输出
1 4 6 2 8 5 3 7 10 9
a b c d e f g h i j  

我实际上得到了以下输出

4 6 2 8 5 3 7 10 9 0
b c d e f g h i j `*@ 

有人可以提供一些指示,说明为什么跳过列表中的第一个元素?我知道我也可以在不使用变量参数列表的情况下做同样的事情,但我只是尝试这是否可行。

2 个答案:

答案 0 :(得分:2)

您的第一个元素被放入T val参数,而不是va_list v;。这是因为va_start(v, val)设置v的var-args在 val之后开始,而不是包括 val。有一些documentation

答案 1 :(得分:1)

您正在使用val参数中的列表的第一部分,因此您实际上列表中的元素少于您使用size指示的元素:

 void PrintValues(int size, T val, ...)
                            ^^^^^

因此,在第一种情况下,val将为1,第二种情况为a。一个可能的解决方法是删除val arg:

void PrintValues(int size, ...)

并更改您的va_start

va_start(v,size);

我意识到你只是在尝试,但这不是类型安全的,我们现在有variadic templates和C ++ 11。虽然因为你只使用一种类型std ::: initializer_list也是一个可行的替代方案,如上一个链接所述。