2

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

#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 `*@ 

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

4

2 回答 2

2

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

于 2013-04-29T16:11:03.063 回答
1

您正在参数中吃掉列表的第一部分,val因此您的列表中的元素实际上比您用 指示的少一个size

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

所以在第一种情况下val1和第二种情况下a。一种可能的解决方法是删除valarg:

void PrintValues(int size, ...)

并改变你的va_start

va_start(v,size);

我意识到你只是在试验,但这不是类型安全的,我们现在有 C++11的可变参数模板。尽管由于您只使用一种类型 std:::initializer_list 也是一种可行的选择,如上一个链接中所述。

于 2013-04-29T16:13:13.677 回答