将一个以 unique_ptr 作为参数的成员函数插入到映射中

问题描述

我正在尝试创建一个系统,其中有一个类(“Delegator”)可以自动将“任务”委托给“组件”,并且组件应该将任务委托给它的方法之一(“处理程序”) .委托人持有字符串(组件名称)到组件指针的映射,组件持有字符串(处理程序名称)到处理程序的映射。任务包含它们应该被委派给的组件的名称、应该被调用的组件处理程序的名称以及应该被操作的数据。任务作为 unique_ptrs 传递。我也想拥有它,以便将来可以根据需要添加组件。我几乎让它工作了,但我被一个我似乎无法解决错误挂了。以下是相关代码(抱歉代码转储):

委托人:

class Delegator{ 

    public:

        Delegator() {}

        void registerComponent(Component &component) {
            std::cout << "Registering component " << component.getName() << " with the Delegator" << endl;
            componentMap[component.getName()] = &component;
        }

        void delegate(unique_ptr<Task> task) {
            std::cout << "Delegating command " << (*task).getCommand() << " to " << (*task).getLocalComp() << endl;
            (*componentMap[(*task).getLocalComp()]).executeTask(move(task));
        }

    private:
        map<string,Component*> componentMap;

};

组件:

#include "Task.h"

using namespace std;

class Component {

public:
    // Constructor
    Component(string name): name(name) {}

    // Types
    typedef boost::function<void (unique_ptr<Task>)> task_handler;
    typedef map<string,task_handler> task_map;

    // Methods
    void registerHandler(string name,task_handler h){
        std::cout << "Registering handler " << name << " with component " << this->getName() << endl;
        cmds[name] = h;
    }

    void executeTask(unique_ptr<Task> task){
        std::cout << "Component " << this->getName() << " executing task " << (*task).getCommand() << endl;
        try{
            task_handler handler = cmds[(*task).getCommand()];
            handler(move(task));
        } catch (std::exception& e) {
            std::cerr << "Tried calling unregistered or nonexistent task handler: " << e.what() << std::endl;
        }
    }

    string getName() {return name;}

private:

    string name;
    task_map cmds;

};

一个示例组件:

#include "Component.h"

class Adder: public Component {

public:
    Adder(): Component("Adder"){
        cout << "Initializing Adder Component" << endl;
        registerHandler("add1",boost::lambda::bind(&Adder::add1,this,boost::lambda::_1));
//      ^^^^^^^^^^^^^^^ error
        cout << "Adder Component finished initializing" << endl;
    }

    void add1(unique_ptr<Task> task) {
        (*task).setData((*task).getData() + 1);
    }

};

主要:

#include "include/Delegator.h"
#include "include/Adder.h"
#include "include/Subtracter.h"
#include "include/Task.h"
#include "include/Cmds.h"

int main() {

    // Initialize Tasks
    unique_ptr<Task> task = make_unique<Task>("add1","Adder","",1);
    
    // Initialize Delegator
    Delegator d;

    // Initialize Components
    Adder adder = Adder();

    // Register Components
    d.registerComponent(adder);

    cout << endl << "Registration Complete\n" << endl;

    // Do stuff

    (*task).printStatus();

    d.delegate(move(task));

    (*task).printStatus();
}

在 Adder 类中没有 registerHandler() 行的情况下,代码编译得很好。添加该行后,我收到以下错误

[build] In file included from /usr/local/include/boost/lambda/core.hpp:50,[build]                  from /usr/local/include/boost/lambda/bind.hpp:15,[build]                  from .../auto_delegate_demo/include/Component.h:6,[build]                  from .../auto_delegate_demo/include/Delegator.h:3,[build]                  from .../auto_delegate_demo/main.cpp:2:
[build] /usr/local/include/boost/lambda/detail/function_adaptors.hpp: In instantiation of ‘static Result boost::lambda::function_adaptor<Result (Object::*)(Arg1)>::apply(Result (Object::*)(Arg1),Object*,A1&) [with RET = void; A1 = const std::unique_ptr<Task>; Object = Adder; Arg1 = std::unique_ptr<Task>; Result = void]’:
[build] /usr/local/include/boost/lambda/detail/actions.hpp:96:26:   required from ‘static RET boost::lambda::function_action<3,T>::apply(A1&,A2&,A3&) [with RET = void; A1 = void (Adder::* const)(std::unique_ptr<Task>); A2 = Adder* const; A3 = const std::unique_ptr<Task>; T = boost::lambda::detail::unspecified]’
[build] /usr/local/include/boost/lambda/detail/lambda_functor_base.hpp:437:34:   required from ‘RET boost::lambda::lambda_functor_base<boost::lambda::action<3,Act>,Args>::call(A&,B&,C&,Env&) const [with RET = void; A = const std::unique_ptr<Task>; B = const boost::tuples::null_type; C = const boost::tuples::null_type; Env = const boost::tuples::null_type; Act = boost::lambda::function_action<3>; Args = boost::tuples::tuple<void (Adder::* const)(std::unique_ptr<Task>),Adder* const,const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >,boost::tuples::null_type,boost::tuples::null_type>]’
[build] /usr/local/include/boost/lambda/detail/lambda_functors.hpp:203:6:   required from ‘typename boost::lambda::lambda_functor<Base>::inherited::sig<boost::tuples::tuple<const A&,boost::tuples::null_type> >::type boost::lambda::lambda_functor<Base>::operator()(const A&) const [with A = std::unique_ptr<Task>; T = boost::lambda::lambda_functor_base<boost::lambda::action<3,boost::lambda::function_action<3> >,boost::tuples::tuple<void (Adder::* const)(std::unique_ptr<Task>),boost::tuples::null_type> >; typename boost::lambda::lambda_functor<Base>::inherited::sig<boost::tuples::tuple<const A&,boost::tuples::null_type> >::type = void]’
[build] /usr/local/include/boost/function/function_template.hpp:158:11:   required from ‘static void boost::detail::function::void_function_obj_invoker1<FunctionObj,R,T0>::invoke(boost::detail::function::function_buffer&,T0) [with FunctionObj = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3,boost::tuples::null_type> > >; R = void; T0 = std::unique_ptr<Task>]’
[build] /usr/local/include/boost/function/function_template.hpp:940:38:   required from ‘void boost::function1<R,T1>::assign_to(Functor) [with Functor = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3,boost::tuples::null_type> > >; R = void; T0 = std::unique_ptr<Task>]’
[build] /usr/local/include/boost/function/function_template.hpp:720:7:   required from ‘boost::function1<R,T1>::function1(Functor,typename boost::enable_if_<(! boost::is_integral<Functor>::value),int>::type) [with Functor = boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<3,boost::tuples::null_type> > >; R = void; T0 = std::unique_ptr<Task>; typename boost::enable_if_<(! boost::is_integral<Functor>::value),int>::type = int]’
[build] /usr/local/include/boost/function/function_template.hpp:1086:16:   required from ‘boost::function<R(T0)>::function(Functor,int>::type = int]’
[build] .../auto_delegate_demo/include/Adder.h:10:91:   required from here
[build] /usr/local/include/boost/lambda/detail/function_adaptors.hpp:395:22: error: use of deleted function ‘std::unique_ptr<_Tp,_Dp>::unique_ptr(const std::unique_ptr<_Tp,_Dp>&) [with _Tp = Task; _Dp = std::default_delete<Task>]’
[build]   395 |     return (o->*func)(a1);
[build]       |            ~~~~~~~~~~^~~~
[build] In file included from /opt/rh/devtoolset-9/root/usr/include/c++/9/memory:80,[build]                  from /usr/local/include/boost/function/function_base.hpp:16,[build]                  from /usr/local/include/boost/function/detail/prologue.hpp:17,[build]                  from /usr/local/include/boost/function.hpp:30,[build]                  from .../auto_delegate_demo/include/Component.h:5,[build]                  from .../auto_delegate_demo/main.cpp:2:
[build] /opt/rh/devtoolset-9/root/usr/include/c++/9/bits/unique_ptr.h:414:7: note: declared here
[build]   414 |       unique_ptr(const unique_ptr&) = delete;
[build]       |       ^~~~~~~~~~
[build] In file included from /usr/local/include/boost/lambda/core.hpp:50,[build]                  from .../auto_delegate_demo/main.cpp:2:
[build] /usr/local/include/boost/lambda/detail/function_adaptors.hpp:395:25: error: return-statement with a value,in function returning ‘void’ [-fpermissive]
[build]   395 |     return (o->*func)(a1);
[build]       |                         ^

提前致谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)