【问题标题】:confused about syntax in functional library std::bind对函数库 std::bind 中的语法感到困惑
【发布时间】:2019-12-14 18:54:06
【问题描述】:
#include <iostream>
#include <functional>
class Solver{
public:
    void print(){
        std::cout << "i solved" << std::endl;
    }
};

class ThingHandler{
public:
    void handleThing(Solver& solver){
        std::cout << "i handled something " << std::endl;
        solver.print();
    }
};

class CantHandle{
public:
    void needHelp(std::function<void(Solver&)> handleThing){
        handleThing(); // how do i here pass Solver as a parameter?
    }
};



int main() {
    ThingHandler thingHandler;
    CantHandle cantHandle;
    Solver solver;
    auto fp = std::bind(&ThingHandler::handleThing, thingHandler,solver);
    cantHandle.needHelp(fp);
    return 0;
}

在“CantHandle”类中,当我调用辅助函数时,它会要求一个参数。这是有道理的,因为被调用的函数是handleThing,它将一个对求解器的引用作为参数。但我似乎无法弄清楚 ThingHandler 类中的语法。不应该 handleThing 已经绑定了参数吗?我收到以下错误“不匹配调用‘(std::function) ()”

完整的错误信息:

错误:对‘(std::function) ()’的调用不匹配 23 |
处理事物(); // 我如何在这里将 Solver 作为参数传递?笔记: 候选人:'_Res std::function<_res ...>::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {求解器&}]’ 685 |函数<_res>:: |
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/c++/9/bits/std_function.h:685:5:注意:候选 需要 1 个参数,提供 0 个参数 gmake[3]: * [CMakeFiles/funcObj.dir/build.make:63: CMakeFiles/funcObj.dir/main.cpp.o] 错误 1 ​​gmake[2]: 强> [CMakeFiles/Makefile2:73: CMakeFiles/funcObj.dir/all] 错误 2 gmake[1]: [CMakeFiles/Makefile2:85: CMakeFiles/funcObj.dir/rule] 错误 2 gmake: * [Makefile:118: funcObj] 错误 2

【问题讨论】:

  • 请附上完整的错误信息
  • 由于您在std::bind 调用中没有使用占位符(例如_1),因此它提供了一个参数为0 的函子。 needHelp 需要一个带有 1 个参数的函子。
  • @HolyBlackCat 如何绑定占位符?你的意思是像 std::bind(&ThingHandler::handleThing, thingHandler,std::placeholders::_1) 但是在这种情况下我应该在哪里包含 Solver?
  • 我认为你的问题不是语法而是语义。您有一个函数 needHelp(),它接受需要 Solver 参数的函数,但 needHelp() 无法提供该参数。那么为什么needHelp() 期望std::function&lt;void(Solver&amp;) 而不是std::function&lt;void()&gt;
  • @JaMiT void(void)0_o

标签: c++


【解决方案1】:

needHelp 方法需要一个带一个参数的函数,但您想传递一个不带参数的函数。改变这个:

void needHelp(std::function<void(Solver&)> handleThing){

void needHelp(std::function<void()> handleThing){

使用 lambda 而不是 bind 通常更易于编写和阅读,并且当您可以接受任何可调用时,通常不需要使用 std::function

#include <iostream>

struct Solver{
    void print(){ 
        std::cout << "i solved" << std::endl; 
    }
};

struct ThingHandler{
    void handleThing(Solver& solver){
        std::cout << "i handled something " << std::endl;
        solver.print();
    }
};

struct CantHandle{
    template <typename F>
    void needHelp(F f){
        f();
    }
};   

int main() {
    ThingHandler thingHandler;
    CantHandle cantHandle;
    Solver solver;   
    cantHandle.needHelp(
        [&solver,&thingHandler](){
            thingHandler.handleThing(solver);
        }
    );
    return 0;
}

【讨论】:

    【解决方案2】:

    CantHandle 类中更改您的方法并添加一个参数为Solver 类型,如下所示并传递数据(Solver 对象):

    class CantHandle{
    public:
        void needHelp(std::function<void(Solver&)> handleThing, Solver data){
            handleThing(data); // how do i here pass Solver as a parameter?
        }
    };
    

    主要是在fp 之后传递solver 作为Solver 对象:

    int main() {
        ThingHandler thingHandler;
        CantHandle cantHandle;
        Solver solver;
        auto fp = std::bind(&ThingHandler::handleThing, thingHandler,solver);
        cantHandle.needHelp(fp, solver);
        return 0;
    }
    

    输出将是:

    i handled something
    i solved
    

    根据this linkthis

    【讨论】:

    • “我的答案是你的输出。为什么投反对票?”我没有投反对票,但你答案中的代码无法编译。您没有将占位符传递给 std::bind,因此只能在不带参数的情况下调用生成的仿函数。
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多