You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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表达式直接绑定参数,无需预定义包装函数:

  1. 引入<functional>头文件:std::function定义在该头文件中
  2. 修改结构体成员类型:将原始函数指针替换为std::function<void()>
  3. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:20:39