鱼C论坛

 找回密码
 立即注册
查看: 1708|回复: 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列)

这是怎么回事?

这些代码可能有影响:
  1. // threads.h
  2. #include <condition_variable>
  3. #include <functional>
  4. #include <thread>
  5. #include <mutex>
  6. #include <queue>
  7. #include <unordered_map>

  8. namespace choices
  9. {
  10.         enum state
  11.         {
  12.                 state_running,
  13.                 state_free,
  14.                 state_paused,
  15.                 state_stopped
  16.         };
  17. };

  18. class BasicThread
  19. {
  20.         friend class DistributeThread;
  21.         public:
  22.                 std::string name = "Basic";
  23.                 BasicThread(const char*);
  24.                 choices::state get_state();
  25.                 void stop();
  26.                 std::unique_lock<std::mutex> * pause();
  27.                 void resume(std::unique_lock<std::mutex> &);
  28.         protected:
  29.                 // 一个用来挂起并唤醒线程的环境变量
  30.                 std::condition_variable alarm;
  31.                 std::unique_lock<std::mutex> *lock;
  32.                 std::mutex mutex;
  33.                 std::queue<int (*)()> queue;
  34.                 std::thread *thread;
  35.                 choices::state state = choices::state_free;
  36.                 bool running = true;
  37.                 void run();
  38.                 void sleep();
  39.         public:
  40.                 template <typename... argument_type>
  41.                 void work(int (*function)(...), argument_type ...args)
  42.                 {
  43.                         this->queue.push(std::bind(function), args...);
  44.                 };
  45. };

  46. class DistributeThread
  47. {
  48.         public:
  49.                 std::string name = "Distributor";
  50.                 BasicThread * create(const char*);
  51.         protected:
  52.                 // 所有线程及锁的存储点
  53.                 std::unordered_map<std::string, BasicThread*> threads;
  54.                 std::unordered_map<std::string, std::unique_lock<std::mutex>> locks;
  55. };
复制代码
  1. // threads.cpp
  2. #include "threads.h"

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

  10. // 获取线程状态
  11. choices::state BasicThread::get_state()
  12. {
  13.         return this->state;
  14. };

  15. // 暂停线程
  16. [[nodiscard]]
  17. std::unique_lock<std::mutex> * BasicThread::pause()
  18. {
  19.         this->state = choices::state_paused;
  20.         std::unique_lock<std::mutex> *lock = new std::unique_lock<std::mutex>(this->mutex);
  21.         return lock;
  22. };

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

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

  34. // 停止运行线程
  35. void BasicThread::stop()
  36. {
  37.         this->running = false;
  38.         // 叫醒线程
  39.         this->alarm.notify_all();
  40.         this->thread->join();
  41. };

  42. // 线程内部运行部分
  43. void BasicThread::run()
  44. {
  45.         this->lock = new std::unique_lock<std::mutex>(this->mutex);
  46.         this->lock->unlock();
  47.         int (*function)();
  48.         while (this->running)
  49.         {
  50.                 this->state = choices::state_running;
  51.                 function = this->queue.front();
  52.                 function();
  53.                 this->queue.pop();
  54.                 if (this->queue.empty())
  55.                 {
  56.                         this->sleep();
  57.                 };
  58.         };
  59. };

  60. // 线程创建部分
  61. BasicThread * DistributeThread::create(const char* name)
  62. {
  63.         std::string name_string = name;
  64.         if (this->threads.find(name_string) != this->threads.end())
  65.         {
  66.                 throw errors::ThreadExistError();
  67.         };
  68.         BasicThread *new_thread = new BasicThread(name);
  69.         this->threads[name_string] = new_thread;
  70.         this->locks[name_string] = std::unique_lock<std::mutex>(new_thread->mutex);
  71.         return new_thread;
  72. };
复制代码

请问怎么修复这个问题?
最佳答案
2023-7-31 13:52:23
根据编译器的错误提示,问题出现在使用了 std::thread 的地方。具体地,在你的代码中,函数模板 work() 的实现中有一个问题,以及 BasicThread 构造函数中启动线程的地方也有问题。

首先,让我们来修复 work() 函数模板的问题。在你的代码中,你尝试将函数指针和参数一起存储到队列中,但是绑定函数对象 std::bind() 的调用方式不正确。下面是修复后的代码:
  1. template <typename... argument_type>
  2. void work(int (*function)(argument_type...), argument_type... args)
  3. {
  4.     this->queue.push(std::bind(function, args...));
  5. }
复制代码

接下来,修复 BasicThread 构造函数中启动线程的问题。你在构造函数中创建了一个新的线程,并将成员函数 run() 作为线程的入口函数,但是你没有正确地传递类实例的指针。下面是修复后的代码:
  1. BasicThread::BasicThread(const char* name)
  2. {
  3.     this->name.assign(name);
  4.     this->state = choices::state_free;
  5.     this->thread = new std::thread(&BasicThread::run, this); // 修复此行
  6. }
复制代码

通过以上的修改,你应该能够解决编译器报错的问题。请重新编译你的代码并检查问题是否已经修复。如有其他问题,请随时提问。






























小甲鱼最新课程 -> https://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()函数时提供了适当的参数。

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

使用道具 举报

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

首先,让我们来修复 work() 函数模板的问题。在你的代码中,你尝试将函数指针和参数一起存储到队列中,但是绑定函数对象 std::bind() 的调用方式不正确。下面是修复后的代码:
  1. template <typename... argument_type>
  2. void work(int (*function)(argument_type...), argument_type... args)
  3. {
  4.     this->queue.push(std::bind(function, args...));
  5. }
复制代码

接下来,修复 BasicThread 构造函数中启动线程的问题。你在构造函数中创建了一个新的线程,并将成员函数 run() 作为线程的入口函数,但是你没有正确地传递类实例的指针。下面是修复后的代码:
  1. BasicThread::BasicThread(const char* name)
  2. {
  3.     this->name.assign(name);
  4.     this->state = choices::state_free;
  5.     this->thread = new std::thread(&BasicThread::run, this); // 修复此行
  6. }
复制代码

通过以上的修改,你应该能够解决编译器报错的问题。请重新编译你的代码并检查问题是否已经修复。如有其他问题,请随时提问。






























小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-22 07:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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