Я пытаюсь написать обобщенный c векторный класс, используя понятия шаблонов и variadi c аргументов . Суть моего объявления класса Vector и его атрибутов выглядит следующим образом.
template<unsigned size, typename T>
struct Vector {
T data[size];
};
Пример
В приведенном ниже примере я создал 2 вектора 3, один из которых типа int
другой с типом float
. Затем я вызываю функцию Set (реализация в следующем разделе), передавая одни и те же параметры, отличающиеся только типами. Результаты для вектора типа int
верны, но результат для вектора типа float
не соответствует ожиданиям.
Math::Vector<3, int> i_vec3;
i_vec3.Set(1, 0, 2);
std::cout << i_vec3 << '\n';
Math::Vector<3, float> f_vec3;
f_vec3.Set(1.0f, 0.0f, 2.0f);
std::cout << f_vec3 << '\n';
Outuput
1,0,2
1,0,0
Ожидаемый выход
1,0,2
1,0,2
Наблюдение: При вызове va_arg(va_list ap, type)
с int
как type
результат верный. Но при использовании других типов, таких как float
, просто возвращается 0.
Реализация метода Set
Member с аргументами variadi c.
void Set(T v, ...) {
va_list args;
va_start(args, v);
data[0] = v;
for (unsigned i = 1; i < size; ++i)
data[i] = va_arg(args, T);
va_end(args);
}
Воспроизводимый пример
Вот минимальная версия задачи для тестирования.
#include <iostream>
#include <cstdarg>
namespace Math {
template<unsigned size, typename T>
struct Vector {
T data[size];
void Set(T v, ...) {
va_list args;
va_start(args, v);
data[0] = v;
for (unsigned i = 1; i < size; ++i)
data[i] = va_arg(args, T);
va_end(args);
}
};
template<unsigned size, typename T>
std::ostream& operator<<(std::ostream& os, const Vector<size, T>& v) {
os << v.data[0];
for (unsigned i = 1; i < size; ++i)
os << ',' << v.data[i];
return os;
}
}
int main() {
Math::Vector<3, int> i_vec3;
i_vec3.Set(1, 0, 2);
std::cout << i_vec3 << '\n';
Math::Vector<3, float> f_vec3;
f_vec3.Set(1.0f, 0.0f, 2.0f);
std::cout << f_vec3 << '\n';
return 0;
}
Замечания
Это моя первая попытка рассуждать о вариациях c, поэтому было бы здорово узнать, какие у меня заблуждения вызывают этот неожиданный результат.