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

如何为含std::any与std::function成员的类实现移动构造函数

问题:vxWorks下PosixTimer移动构造函数导致std::function/std::any异常

运行环境

  • 操作系统:vxWorks
  • C标准:C17
  • 编译器:Clang 16

问题描述

在为自定义PosixTimer类实现移动构造函数时,遇到两个异常问题:

  • 处理std::function<void(const std::any&)>类型成员时,目标对象无有效值,调用时抛出std::bad_function_call异常;
  • 处理std::any类型成员时,调用std::any_cast会抛出std::bad_any_cast异常。

已尝试的实现

std::function相关尝试

this->callback = source.callback;
this->callback.swap(source.callback);
this->callback = std::move(source.callback);

std::any相关尝试

this->callback_data = source.callback_data;
this->callback_data.swap(source.callback_data);

完整代码

posix_timer.hpp

#include <any>
#include <map>
#include <ctime>
#include <string>
#include <csignal>
#include <cstdint>
#include <functional>

typedef int signal_t;

class PosixTimer
{
public:
    static inline const int signal_rt_min = SIGRTMIN, signal_rt_max = SIGRTMAX;
    using callback_timer_t = std::function<void(const std::any&)>;
    PosixTimer(callback_timer_t callback, const std::any& callback_data, 
        bool periodic = false) : PosixTimer(periodic)
    {
        this->callback = callback;
        this->callback_data = callback_data;
    }

    PosixTimer(){}

    PosixTimer(const PosixTimer& instance);//; = delete;  //Delete copy constructor
    PosixTimer& operator=(const PosixTimer& instance);// = delete; //Delete Copy Assignment 

    PosixTimer(PosixTimer&& source);
    PosixTimer& operator=(PosixTimer&& source);

    ~PosixTimer();
    
    void registerCallback(callback_timer_t callback, const std::any& callback_data);

private:
    static inline std::map<signal_t, bool>  signal_usage_status;
    signal_t                    signal_id;
    static inline std::uint8_t  total_timer_count = 0;
    std::uint8_t                timer_count = 0;
    bool                        periodic;
    std::uint64_t               timeout;// in nano-seconds
    timer_t                     timer_id;
    sigset_t                    mask;
    std::any                    callback_data;
    struct sigevent             sev;
    struct sigaction            sa;
    struct itimerspec           its;
    bool                        timer_valid {false};
    static void handler(int sig, siginfo_t *si, void *uc);
    callback_timer_t            callback;
};

posix_timer.cpp

PosixTimer::PosixTimer(PosixTimer &&source)
{
    std::cout << "Inside Move Constructor PosixTimer::PosixTimer(PosixTimer &&source)\n";
    this->timer_id = source.timer_id;
    this->timer_valid = source.timer_valid;
    this->signal_id = source.signal_id;
    this->timer_count = source.timer_count;
    this->periodic = source.periodic;
    this->timeout = source.timeout;// in nano-seconds
    this->mask = source.mask;
    //this->callback_data = source.callback_data;
    this->callback_data.swap(source.callback_data);
    this->sev = source.sev;
    this->sa = source.sa;
    this->its = source.its;
//  this->callback = source.callback;
//  this->callback.swap(source.callback);
    this->callback = std::move(source.callback);
    //Reset source timer_id to 0 and timer validity (timer_valid) to false
    source.timer_id = 0;
    source.timer_valid = false;
}

PosixTimer &PosixTimer::operator=(PosixTimer &&source)
{
    std::cout << "Inside Move Assignment PosixTimer &PosixTimer::operator=(PosixTimer &&source)\n";
    if (this != &source) //performs no operation if you try to assign the object to itself
    {
        this->timer_id = source.timer_id;
        this->timer_valid = source.timer_valid;
        this->signal_id = source.signal_id;
        this->timer_count = source.timer_count;
        this->periodic = source.periodic;
        this->timeout = source.timeout;// in nano-seconds
        this->mask = source.mask;
//      this->callback_data = source.callback_data;
        this->callback_data.swap(source.callback_data);
        this->sev = source.sev;
        this->sa = source.sa;
        this->its = source.its;
//      this->callback = source.callback;
//      this->callback.swap(source.callback);
        this->callback = std::move(source.callback);
        //Reset source timer_id to 0 and timer validity (timer_valid) to false
        source.timer_id = 0;
        source.timer_valid = false; 
    }
    return *this;
}

void PosixTimer::registerCallback(callback_timer_t callback, std::any callback_data)
{
    try
    {
        this->callback_data = callback_data;
        this->callback = callback;
    }
    catch(const std::exception& e)
    {
        std::cerr << "PosixTimer::registerCallback(callback_timer_t callback, const std::any& callback_data) : " << e.what() << std::endl;
    }
}

main.cpp

#include "posix_timer.hpp"
#include <iostream>
#include <vector>
#include <any>

void handler(const std::any& data)
{
    try
    {
        std::cout << "Data Type : " << data.type().name() << std::endl;
        std::cout << "Signal Handler called. Time Delay : " << std::any_cast<int>(data) << std::endl;
    }
    catch(const std::exception& e)
    {
        std::cerr << "Main::handler : " << e.what() << '\n';
    }
    
    
}

int main(int argc, char const *argv[])
{
    // std::any data = std::make_any<int>(10);
    std::vector<PosixTimer> vt;
    PosixTimer::initialize();
     {
        PosixTimer t;
        
        bool return_status = t.create(PosixTimer::in_seconds(10), true);
        t.registerCallback(handler, 10);
        vt.push_back(std::move(t));
     }
    while (true)
    {
        sleep(25);
        //vt.at(0).registerCallback(handler, 5);
        vt.at(0).update(PosixTimer::in_seconds(5));
    }
    
    return 0;
}

运行输出

Inside constructor PosixTimer::PosixTimer()
PosixTimer::create(std::uint64_t timeout, bool periodic) called
PosixTimer::create(void) called
Signal ID : 34
TIMER START CALLED, Timer ID : 0
Timer Value Sec: 10     nsec: 0
Timer Interval Value Sec: 10    nsec: 0
PosixTimer::registerCallback Callback Data : 10
Inside destructor PosixTimer::~PosixTimer()
timer->callback is empty
terminate called after throwing an instance of 'std::bad_function_call'
  what():  bad_function_call
Aborted

内容的提问来源于stack exchange,提问作者Dark Sorrow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:34:57