我一直试图在下面的代码中找出我所面临的问题。
#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 `*@
有人可以提供一些指示,说明为什么跳过列表中的第一个元素?我知道我也可以在不使用变量参数列表的情况下做同样的事情,但我只是尝试这是否可行。
答案 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也是一个可行的替代方案,如上一个链接所述。