带有模板问题的指针的动态数组

Dynamic array of pointers with template problem

本文关键字:指针 数组 动态 问题      更新时间:2023-10-16

如何使用此类动态创建数组(这是arduino的Teensy Step库(:

class StepControl : IPitHandler, IDelayHandler
{
public:
...
StepControl();
template<size_t N> void move(Stepper* (&motors)[N], float relSpeed = 1);
...

然后这是这个类的用法,它 100% 工作但静态:

Stepper J1(0, 1), J2(2, 3), J3(4, 5), J4(6, 7), J5(8, 9), J6(10, 11);
StepControl <> controller;
Stepper *robot[] = {&J1,&J2,&J3,&J4,&J5,&J6};
controller.move(robot);

我想像这样做,但动态创建数组:

Stepper J1(0, 1), J2(2, 3), J3(4, 5), J4(6, 7), J5(8, 9), J6(10, 11);
StepControl <> controller;
int j = 4
Stepper *robot[j];
robot[0]=&J1;
robot[1]=&J2;
robot[2]=&J2;
robot[3]=&J2;
controller.move(robot);

结果: 错误:调用"步进控制<>::移动(步进器* [j]("没有匹配函数

怎么做?

目前,StepControl::move()方法被编写为仅接受编译已知大小的数组。这意味着,如果编译器可以计算出数组的大小,如下所示:

// size is inferred at compile time to be 6
Stepper* robot[] = {&J1,&J2,&J3,&J4,&J5,&J6};

然后,编译器可以成功地将controller.move(robot);与以下模板实例化匹配:

void move<>(Stepper* (&motors)[6], float relSpeed = 1);

但是,如果在编译时不知道数组大小是多少,编译器就无法将调用move与特定模板实例化相匹配。当你写的时候

int j = 4;
Stepper *robot[j];

由于j不是编译时常量,因此robot实际上是一个动态大小的非标准堆栈数组。一些编译器允许这样做,但结果是在编译时无法知道robot的大小。


要解决此问题,您可以在编译时始终确定数组大小,如下所示:

if (needsToBeSix){
Stepper *robots[6] = ...;
controller.move(robots);
} else if (needsToBeFour){
Stepper *robots[4] = ...;
controller.move(robots);
}

或者,如果您确实需要动态大小的数组,请使用std::vector

class StepControl {
...
void move(std::vector<Stepper*>& motors, float relSpeed = 1){
// size can be queried at runtime as follows
const size_t N = motors.size();
// rest of method;
}
...
}
...
std::vector<Stepper*> robot { &J1, &J2, &J3, &J4 };
if (needTwoMore){
robot.push_back(&J5);
robot.push_back(&J6);
}
controller.move(robot);

就像改变伊格尔的想法一样。将在库中实现矢量接口,以便您可以按照建议使用它。