C++如何传递带参数的函数指针以简化动画代码实现
如何在C++中传递带参数的函数指针以简化代码结构?
你需要传递带参数的函数到LedAnimationArray中,避免为doUserAnimation编写大量包装函数和预定义_userAnimations数组,希望直接实现类似LedAnimationArray b = {"usertest", doUserAnimation(animationNumber-gDefaultAnimationCount)};的效果。
原代码
#include <string> #include <iostream> typedef void (*AnimationFunction) (); int gDefaultAnimationCount = 0; struct LedAnimationArray { std::string name; AnimationFunction function; }; void A_AllDark() { std::cout << "BuiltInAllDark"; std::cout << '\n'; } void A_AllLight() { std::cout << "BuiltInAllLight"; std::cout << '\n'; } void doUserAnimation(int animationNumber) { std::cout << "UserAnimation_"; std::cout << animationNumber; std::cout << '\n'; } LedAnimationArray _builtInAnimations[] { {"Off", A_AllDark}, {"On", A_AllLight} }; // [Start want to remove this code] void UserAni1() { doUserAnimation(0); } void UserAni2() { doUserAnimation(1); } LedAnimationArray _userAnimations[] { {"UserAni1",UserAni1}, {"UserAni2",UserAni2} }; // [End want to remove this code] LedAnimationArray getAnimation(int animationNumber) { if (animationNumber > gDefaultAnimationCount - 1) { LedAnimationArray b = {"usertest",_userAnimations[animationNumber-gDefaultAnimationCount].function}; // 我希望实现类似这样的可行代码 :) //LedAnimationArray b = {"usertest", doUserAnimation(animationNumber-gDefaultAnimationCount)}; return b; } else { return _builtInAnimations[animationNumber]; } } int main() { gDefaultAnimationCount = sizeof(_builtInAnimations) / sizeof(_builtInAnimations[0]) ; getAnimation(0).function(); getAnimation(1).function(); getAnimation(2).function(); getAnimation(3).function(); return 0; }
实现方案
原始的函数指针无法存储绑定了参数的函数,需要改用C++的std::function承载可调用对象,结合lambda表达式直接绑定参数,无需预定义包装函数:
- 引入
<functional>头文件:std::function定义在该头文件中 - 修改结构体成员类型:将原始函数指针替换为
std::function<void()> - 在
getAnimation中直接构造带参数的可调用对象:用lambda捕获目标参数,封装doUserAnimation的调用
修改后的完整代码
#include <string> #include <iostream> #include <functional> // 引入std::function头文件 int gDefaultAnimationCount = 0; struct LedAnimationArray { std::string name; std::function<void()> function; // 替换原始函数指针 }; void A_AllDark() { std::cout << "BuiltInAllDark\n"; } void A_AllLight() { std::cout << "BuiltInAllLight\n"; } void doUserAnimation(int animationNumber) { std::cout << "UserAnimation_" << animationNumber << '\n'; } LedAnimationArray _builtInAnimations[] { {"Off", A_AllDark}, {"On", A_AllLight} }; LedAnimationArray getAnimation(int animationNumber) { if (animationNumber > gDefaultAnimationCount - 1) { int userAniIdx = animationNumber - gDefaultAnimationCount; // 用lambda捕获参数,直接封装doUserAnimation调用 return {"usertest", [userAniIdx](){ doUserAnimation(userAniIdx); }}; } else { return _builtInAnimations[animationNumber]; } } int main() { gDefaultAnimationCount = sizeof(_builtInAnimations) / sizeof(_builtInAnimations[0]); getAnimation(0).function(); getAnimation(1).function(); getAnimation(2).function(); getAnimation(3).function(); return 0; }
说明
std::function<void()>可以容纳任何无参数、返回值为void的可调用对象,包括普通函数指针、lambda表达式、绑定了参数的函数对象等- lambda表达式
[userAniIdx](){ doUserAnimation(userAniIdx); }捕获了userAniIdx的值,当调用function()时,会执行带该参数的doUserAnimation - 彻底移除了原有的包装函数和
_userAnimations数组,代码结构更简洁,无需预定义所有用户动画的包装
内容的提问来源于stack exchange,提问作者JamesWilliams
相关产品推荐
相关产品推荐

