鱼C论坛

 找回密码
 立即注册
查看: 1351|回复: 2

[已解决]c++ 编译器内部报错

[复制链接]
发表于 2023-7-31 12:41:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我在尝试编译我的源代码的时候,编译器发出了这样的错误:
(MinGW\lib\gcc\x86_64-w64-mingw32\7.3.0\include\c++\bits\invoke.h)
no type named 'type' in 'struct std::__invoke_result<void (BasicThread::*)()>'(89行,5列)
(MinGW\lib\gcc\x86_64-w64-mingw32\7.3.0\include\c++\thread)
no matching function for call to '__invoke(std::__tuple_element_t<0, std::tuple<void (BasicThread::*)()> >)'(233行,29列)
no matching function for call to 'std::thread::_Invoker<std::tuple<void (BasicThread::*)()> >::_M_invoke(std::thread::_Invoker<std::tuple<void (BasicThread::*)()> >::_Indices)'(240行,2列)

这是怎么回事?

这些代码可能有影响:
// threads.h
#include <condition_variable>
#include <functional>
#include <thread>
#include <mutex>
#include <queue>
#include <unordered_map>

namespace choices
{
        enum state 
        {
                state_running,
                state_free,
                state_paused,
                state_stopped
        };
};

class BasicThread
{
        friend class DistributeThread;
        public:
                std::string name = "Basic";
                BasicThread(const char*);
                choices::state get_state();
                void stop();
                std::unique_lock<std::mutex> * pause();
                void resume(std::unique_lock<std::mutex> &);
        protected:
                // 一个用来挂起并唤醒线程的环境变量
                std::condition_variable alarm;
                std::unique_lock<std::mutex> *lock;
                std::mutex mutex;
                std::queue<int (*)()> queue;
                std::thread *thread;
                choices::state state = choices::state_free;
                bool running = true;
                void run();
                void sleep();
        public:
                template <typename... argument_type>
                void work(int (*function)(...), argument_type ...args)
                {
                        this->queue.push(std::bind(function), args...);
                };
};

class DistributeThread
{
        public:
                std::string name = "Distributor";
                BasicThread * create(const char*);
        protected:
                // 所有线程及锁的存储点
                std::unordered_map<std::string, BasicThread*> threads;
                std::unordered_map<std::string, std::unique_lock<std::mutex>> locks;
};
// threads.cpp
#include "threads.h"

// 线程初始化部分
BasicThread::BasicThread(const char* name)
{
        this->name.assign(name);
        this->state = choices::state_free;
        this->thread = new std::thread(run);
};

// 获取线程状态
choices::state BasicThread::get_state()
{
        return this->state;
};

// 暂停线程
[[nodiscard]]
std::unique_lock<std::mutex> * BasicThread::pause()
{
        this->state = choices::state_paused;
        std::unique_lock<std::mutex> *lock = new std::unique_lock<std::mutex>(this->mutex);
        return lock;
};

// 继续线程运行
void BasicThread::resume(std::unique_lock<std::mutex> &lock)
{
        lock.unlock();
};

// 线程完成任务后等待下一个任务(暂时没有下一个任务了)
void BasicThread::sleep()
{
        this->state = choices::state_free;
        this->alarm.wait(*this->lock);
};

// 停止运行线程
void BasicThread::stop()
{
        this->running = false;
        // 叫醒线程
        this->alarm.notify_all();
        this->thread->join();
};

// 线程内部运行部分
void BasicThread::run()
{
        this->lock = new std::unique_lock<std::mutex>(this->mutex);
        this->lock->unlock();
        int (*function)();
        while (this->running)
        {
                this->state = choices::state_running;
                function = this->queue.front();
                function();
                this->queue.pop();
                if (this->queue.empty())
                {
                        this->sleep();
                };
        };
};

// 线程创建部分
BasicThread * DistributeThread::create(const char* name)
{
        std::string name_string = name;
        if (this->threads.find(name_string) != this->threads.end())
        {
                throw errors::ThreadExistError();
        };
        BasicThread *new_thread = new BasicThread(name);
        this->threads[name_string] = new_thread;
        this->locks[name_string] = std::unique_lock<std::mutex>(new_thread->mutex);
        return new_thread;
};
请问怎么修复这个问题?
最佳答案
2023-7-31 13:52:23
根据编译器的错误提示,问题出现在使用了 std::thread 的地方。具体地,在你的代码中,函数模板 work() 的实现中有一个问题,以及 BasicThread 构造函数中启动线程的地方也有问题。

首先,让我们来修复 work() 函数模板的问题。在你的代码中,你尝试将函数指针和参数一起存储到队列中,但是绑定函数对象 std::bind() 的调用方式不正确。下面是修复后的代码:
template <typename... argument_type>
void work(int (*function)(argument_type...), argument_type... args)
{
    this->queue.push(std::bind(function, args...));
}
接下来,修复 BasicThread 构造函数中启动线程的问题。你在构造函数中创建了一个新的线程,并将成员函数 run() 作为线程的入口函数,但是你没有正确地传递类实例的指针。下面是修复后的代码:
BasicThread::BasicThread(const char* name)
{
    this->name.assign(name);
    this->state = choices::state_free;
    this->thread = new std::thread(&BasicThread::run, this); // 修复此行
}
通过以上的修改,你应该能够解决编译器报错的问题。请重新编译你的代码并检查问题是否已经修复。如有其他问题,请随时提问。






























想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-31 12:41:26 | 显示全部楼层
根据报错信息,问题可能出现在std::thread相关的代码部分。报错提示了调用__invoke函数时出现了类型不匹配的错误。

要解决这个问题,你可以尝试采取以下步骤:

1. 确保你的编译器版本与使用的MinGW库版本兼容。某些版本的编译器和库之间可能存在不兼容性问题。尝试更新你的编译器或使用与MinGW库版本相匹配的编译器版本。

2. 检查BasicThread类中使用的函数指针是否正确。确保你传递给work()函数的实际参数与函数指针的类型匹配。

3. 如果你正在使用成员函数作为线程函数,确保使用适当的语法来绑定成员函数。对于成员函数,需要使用std::bind或lambda表达式来绑定该函数。

我注意到你的work()函数使用了模板,并且在使用std::bind时似乎没有传递参数。请确保你在调用work()函数时提供了适当的参数。

通过检查上述步骤并修复潜在的问题,你应该能够解决这个编译错误。如果问题仍然存在,请提供更多相关的代码和错误信息,以便我们能够进一步帮助你解决问题。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-31 13:52:23 | 显示全部楼层    本楼为最佳答案   
根据编译器的错误提示,问题出现在使用了 std::thread 的地方。具体地,在你的代码中,函数模板 work() 的实现中有一个问题,以及 BasicThread 构造函数中启动线程的地方也有问题。

首先,让我们来修复 work() 函数模板的问题。在你的代码中,你尝试将函数指针和参数一起存储到队列中,但是绑定函数对象 std::bind() 的调用方式不正确。下面是修复后的代码:
template <typename... argument_type>
void work(int (*function)(argument_type...), argument_type... args)
{
    this->queue.push(std::bind(function, args...));
}
接下来,修复 BasicThread 构造函数中启动线程的问题。你在构造函数中创建了一个新的线程,并将成员函数 run() 作为线程的入口函数,但是你没有正确地传递类实例的指针。下面是修复后的代码:
BasicThread::BasicThread(const char* name)
{
    this->name.assign(name);
    this->state = choices::state_free;
    this->thread = new std::thread(&BasicThread::run, this); // 修复此行
}
通过以上的修改,你应该能够解决编译器报错的问题。请重新编译你的代码并检查问题是否已经修复。如有其他问题,请随时提问。






























想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 09:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表