C/C++编程:reference to non-static member function must be called

1059 篇文章 285 订阅

主要原因是我使用了函数指针,而函数指针所指函数须得是静态才行


错误代码:

class Solution {
public:
    string ReverseSentence(string str) {

        typedef string::const_iterator const_iter;
        const_iter b = str.begin();
        const_iter e = str.end();
        string ret;
        int first = 1;
        while( b != e ){
            b = find_if( b, e, legal );
            if( b < e ){
                const_iter after = find_if( b, e, illegal ); // 这里的调用出了问题,编译出错reference to non-static member function must be called
                if( ret != "" ) ret = string(b, after) + " " + ret;
                else ret = string(b, after) + ret;
                b = after;
            }
            else{
                if( 1 == first ) return str;
                else first = 2;
            }
        }
        return ret;
    }
private:
     bool legal( char ch ){ return !illegal(ch); } // 这里是问题
     bool illegal( char ch ){ return isspace(ch); }
};

解决

分析上面的错误,应该说的是,find_if的第三个参数应该调用一个non static函数,这是什么原因?我们来看下find_if的代码

template<class InputIterator, class UnaryPredicate>
  InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}

第三个谓词pred是一个非成员函数,因为pred的调用过程只有一个参数,就是*first。但是,对于像bool legal(char ch)这样的成员函数,它是属于类的,所以调用它必须需要对象才可以,这是因为bool legal这样的函数完整的标签是:

bool legal( Solution* this, char ch );

也就是它有一个implicit parameter,这才导致它无法被find_if这样的函数调用,主要是参数不匹配。当然,把这个函数改成static即可。

如果一定要非静态引用怎么办?

#include <string>
#include <memory>
#include "mutex"

#ifndef HV_THREAD_POOL_H_
#define HV_THREAD_POOL_H_

#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <future>
#include <memory>
#include <utility>
#include <stack>

class HThreadPool {
public:
    using Task = std::function<void()>;

    HThreadPool(int size = std::thread::hardware_concurrency())
            : pool_size(size), idle_num(size), status(STOP) {
    }

    ~HThreadPool() {
        stop();
    }

    int start() {
        if (status == STOP) {
            status = RUNNING;
            for (int i = 0; i < pool_size; ++i) {
                workers.emplace_back(std::thread([this]{
                    while (status != STOP) {
                        while (status == PAUSE) {
                            std::this_thread::yield();
                        }

                        Task task;
                        {
                            std::unique_lock<std::mutex> locker(_mutex);
                            _cond.wait(locker, [this]{
                                return status == STOP || !tasks.empty();
                            });

                            if (status == STOP) return;

                            if (!tasks.empty()) {
                                --idle_num;
                                task = std::move(tasks.top());
                                tasks.pop();
                            }
                        }

                        task();
                        ++idle_num;
                    }
                }));
            }
        }
        return 0;
    }

    int clear() {
        std::unique_lock<std::mutex> locker(_mutex);
        if (!tasks.empty()) {
            std::stack<Task>().swap(tasks);
        }
        return 0;
    }

    int stop() {
        if (status != STOP) {
            status = STOP;
            _cond.notify_all();
            for (auto& worker : workers) {
                worker.join();
            }
        }
        return 0;
    }

    int pause() {
        if (status == RUNNING) {
            status = PAUSE;
        }
        return 0;
    }

    int resume() {
        if (status == PAUSE) {
            status = RUNNING;
        }
        return 0;
    }

    int wait() {
        while (1) {
            if (status == STOP || (tasks.empty() && idle_num == pool_size)) {
                break;
            }
            std::this_thread::yield();
        }
        return 0;
    }

    // return a future, calling future.get() will wait task done and return RetType.
    // commit(fn, args...)
    // commit(std::bind(&Class::mem_fn, &obj))
    // commit(std::mem_fn(&Class::mem_fn, &obj))
    template<class Fn, class... Args>
    auto commit(Fn&& fn, Args&&... args) -> std::future<decltype(fn(args...))> {
        using RetType = decltype(fn(args...));
        auto task = std::make_shared<std::packaged_task<RetType()> >(
                std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...));
        std::future<RetType> future = task->get_future();
        {
            std::lock_guard<std::mutex> locker(_mutex);
            tasks.emplace([task]{
                (*task)();
            });
        }

        _cond.notify_one();
        return future;
    }

public:
    enum Status {
        STOP,
        RUNNING,
        PAUSE,
    };
    int                 pool_size;
    std::atomic<int>    idle_num;
    std::atomic<Status> status;
    std::vector<std::thread>    workers;
    std::stack<Task>            tasks;

protected:
    std::mutex              _mutex;
    std::condition_variable _cond;
};

#endif // HV_THREAD_POOL_H_

class myClass{
public:

};

class pool_task{
     HThreadPool *m_threadPool;
     std::string  my_name = "hhhhh" ;
public:
    pool_task(){
        m_threadPool = new HThreadPool(5);
        m_threadPool->start();
    }

    void pool_commit(){
        std::string param = "aaa";
        m_threadPool->commit([this, param] {return this->task(param); });
    }

     void task(const std::string& param){
        printf("aaaaaaaaaa, %s, %s\n", my_name.c_str(), param.c_str());
    }
};

int main(){
    auto *p = new pool_task();
    p->pool_commit();
    getchar();
    return 0;
}







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 这个错误是因为在sort函数的第三个参数中引用了非静态成员函数,而在类定义中若不将成员函数声明为静态成员函数,会默认给成员函数添加一个this指针。而sort函数的第三个参数不允许有指针参数,所以会导致报错。解决这个问题的方法是将成员函数声明为静态成员函数,这样就不会添加this指针了。或者可以考虑将比较函数cmp定义为类外的普通函数,而不是成员函数。这样就可以解决该错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [[C++类静态成员函数]error: reference to non-static member function must be called](https://blog.csdn.net/qq_38337524/article/details/125084848)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [[Leetcode]错误:error: reference to non-static member function must be called](https://blog.csdn.net/weixin_46428351/article/details/123554510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值