簡體   English   中英

無法從std :: bind中推斷出std :: function的模板參數

[英]Could not deduce template argument for std::function from std::bind

我試圖找到一種方法來調用許多類成員函數,每個函數都有不同的參數,在調用之前和之后發生某些已知的功能。

這個包裝函數是我嘗試過的,但是例如對它的最后調用不會編譯錯誤:

'bool Wrapper(Work *,std :: function <bool(Args ...)>,Args && ...)':無法推斷'std :: function <bool的模板參數(double,std :: string, Args ...)>'from'std :: _ Bind <true,bool,std :: _ Pmf_wrap <bool(__ thiscall Work :: *)(double,std :: string),bool,Work,double,std :: string >,Work * const>'

class Work
    {
    public:
        void DoWork(int a, double b, string c);

    private:
        void Pre() {};
        void Post() {};
        bool Step1() { return true; }
        bool Step2(int) { return true; }
        bool Step3(double, string) { return true; }
    };

template<typename... Args>
bool Wrapper(Work *work, std::function<bool(Args...)> func, Args&&... args)
    {
    work->Pre();
    bool ret = func(std::forward<Args>(args)...);
    work->Post();
    return ret;
    }

void Work::DoWork(int a, double b, string c)
{
    if (!Wrapper<>(this, std::bind(&Work::Step1, this))) // error
        return;
    if (!Wrapper<int>(this, std::bind(&Work::Step2, this), a)) // error
        return;
    if (!Wrapper<double, string>(this, std::bind(&Work::Step3, this), b, c)) // error
        return;
}

int main()
{
    Work work;
    work.DoWork(1, 2.0, "three");
    return 0;
}

(將前置和后置功能放在步驟中看起來乍一看似乎更可取,但這是不可取的,因為上面是實際代碼的簡化示例,並且步驟有多個返回位置,並且沒有測試。)

我認為顯式模板參數可以使模板解析成為可能。 我究竟做錯了什么?

使用C ++ 11, std::bind可以替換為lambda,您可以刪除包裝器的模板:

class Work
{
    public:
        void DoWork(int a, double b, string c);

    private:
        void Pre() {};
        void Post() {};
        bool Step1() { return true; }
        bool Step2(int) { return true; }
        bool Step3(double, string) { return true; }

        friend bool Wrapper(Work *work, std::function<bool()> func);
};

bool Wrapper(Work *work, std::function<bool()> func)
{
    work->Pre();
    bool ret = func();
    work->Post();
    return ret;
}

void Work::DoWork(int a, double b, string c)
{
    if (!Wrapper(this, [this]() -> bool { return this->Step1(); }))
        return;
    if (!Wrapper(this, [this, a]() -> bool { return this->Step2(a); }))
        return;
    if (!Wrapper(this, [this, b, c]() -> bool { return this->Step3(b, c); }))
        return;
}

int main()
{
    Work work;
    work.DoWork(1, 2.0, "three");
    return 0;
}

示例: http//coliru.stacked-crooked.com/a/2cd3b3e2a4abfcdc

返回的std::bind或lambda類型不是std::function ,從它們構造std::function是不明確的。

一種解決方案是允許任何仿函數並且不使用std::function

template<typename F, typename... Args>
bool Wrapper(Work &work, F&& func, Args&&... args)
{
    work.Pre();
    const bool ret = std::forward<F>(func)(std::forward<Args>(args)...);
    work.Post();
    return ret;
}

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM