我想使用新的C ++范例(我有一个C ++ 17编译器)对一个小型数学库进行现代化。具体来说,我需要通过构造函数将数组传递给类。
这是"经典"我使用的旧方式。它的工作原理
class Vector {
public:
long double* elements;
public:
Vector(int size, long double *array) {
elements = new long double[size];
for(int i = 0; i < size; i++) {
elements[i] = array[i];
}
};
virtual ~Vector() {
delete []elements;
}
};
int main() {
long double array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
Vector vector = Vector(10, array);
for (int i = 0; i < 10; i++) {
std::cout << vector.elements[i] << std::endl;
}
return 0;
}
所以,我尝试用我对variadic模板和参数包的理解来改变Vector类。它不起作用
class Vector {
public:
long double* elements;
public:
template<typename... Args>
Vector(Args... args){
constexpr int size = sizeof...(Args);
elements = new long double[size]{args...};
}
};
int main() {
long double array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
Vector vector = Vector(array);
for (int i = 0; i < 10; i++) {
std::cout << vector.elements[i] << std::endl;
}
return 0;
}
编译器返回的错误是
错误:初始化
中无法将'long double *'转换为'long double'elements = new long double[size]{args...};
我做错了什么? 此外,我想知道是否可以在main方法和Vector类中使用std :: array而不是raw数组。
答案 0 :(得分:2)
传递类似变量模板的数组不是解决方案。可变参数模板用于将 N 个参数传递给类/函数。但是你只传递了一个参数!
我建议你
我建议您使用所有C ++版本中提供的数组引用:
class Vector {
public:
long double* elements;
public:
template<std::size_t size>
Vector(long double (&array)[size]) {
elements = new long double[size];
for(int i = 0; i < size; i++) {
elements[i] = array[i];
}
};
virtual ~Vector() {
delete []elements;
}
};
顺便说一句,如果可以,请使用矢量。我非常怀疑这个自定义向量类与std::vector
一样高效(没有几何增长或优化的复制和移动)
答案 1 :(得分:1)
根据您的定义
template<typename... Args> Vector(Args... args);
您希望以这种方式使用此构造函数:
Vector vector = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
如果您将构造函数的定义明确地修改为:
,则有可能template<typename... Args>
Vector(Args... args){
constexpr int size = sizeof...(Args);
elements = new long double[size]{static_cast<long double>(args)...};
}
请注意,此类用法不良好做法,您通常应使用std
容器并避免使用new
运营商。
答案 2 :(得分:1)
我不确定这是否能回答你的问题,但我会给你一个一般建议: 我想你想把你自己的逻辑封装到矢量中。 标准库矢量非常先进,您应该使用它,而不是浪费时间编写自己的低级代码。你可以更专注于你需要的逻辑。
您可以定义自己的向量,并仍然使用std :: vector的优点来构建Vector对象。 例如继承:
template<typename T>
class Vector : public std::vector<int>
{
// here comes the implementation of your interface.
}
或作文:
template<typename T>
class Vector {
private:
std::vector<T> elems;
}
在组合的情况下,您必须定义所需的构造函数。
在这两种情况下,您都可以使用自己的Vector,如下所示:
Vector<double> vec1(10); // construct vector with 10 double's each = 0
Vector<double> vec2(10, 5); // construct vector with 10 double's each = 5
Vector<double> vec3{1,2,3,4}; // using initializer list
Vector<double> vec4(somecontainer.begin(), somecontainer.end()); // construct vector by copying elemts from some other container
等
正如您在std :: vector中所看到的,您将获得构建自己的Vector对象所需的所有好处。