门吹西风 2024-07-12 20:47 采纳率: 0%
浏览 3

为何以上代码在vs2020中可以编译通过,可运行,在gcc7.3.0下编译报错?

为何以上代码在vs2020中可以编译通过,可运行,在gcc7.3.0下编译报错?

template<class T, class...ReqContextT>
class AsyncRequestSchedulerT2 final {
public:
    void start(std::unique_ptr<MyClass1> c, ReqContextT&& ...reqContext)
    {
        using AsyncRequestScheduler = AsyncRequestSchedulerT2<T, ReqContextT...>;
        if (c != nullptr) {
            std::vector<std::thread> threads(c->count());
            for (std::size_t pos = 1; pos < c->count(); pos++) {
                threads[pos - 1] = std::thread(&AsyncRequestScheduler::processRequest, *this, std::forward<ReqContextT>(reqContext)...);
            }
            for (std::size_t pos = 0; pos < threads.size(); pos++) {
                threads[pos].join();
            }

        }
        processRequest(std::forward<ReqContextT>(reqContext)...);
    }

    void processRequest(ReqContextT&& ...reqContext)
    {
        std::cout << "processRequest" << std::endl;
    }
};

gcc编译错误

                 from AsyncRequestSchedulerTest2.cpp:12:
/usr/include/c++/7.3.0/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >’:
/usr/include/c++/7.3.0/thread:127:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&); _Args = {MyAsyncRequestSchedulerT<int, AsyncContext&>&, AsyncContext&}]’
test/dt_tests/AsyncRequestSchedulerTest2.cpp:102:41:   required fromvoid MyAsyncRequestSchedulerT<T, ReqContextT>::start(std::unique_ptr<SchedulePolicy>, ReqContextT&& ...) [with T = int; ReqContextT = {AsyncContext&}]’
test/dt_tests/AsyncRequestSchedulerTest2.cpp:120:61:   required from here
/usr/include/c++/7.3.0/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >::_M_invoke(std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >::_Indices)’
  operator()()
  ^~~~~~~~
/usr/include/c++/7.3.0/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext>]
    _M_invoke(_Index_tuple<_Ind...>)
    ^~~~~~~~~
/usr/include/c++/7.3.0/thread:231:4: note:   template argument deduction/substitution failed:
/usr/include/c++/7.3.0/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2}]’:
/usr/include/c++/7.3.0/thread:240:2:   required from ‘struct std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >’
/usr/include/c++/7.3.0/thread:127:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&); _Args = {MyAsyncRequestSchedulerT<int, AsyncContext&>&, AsyncContext&}]’
test/dt_tests/AsyncRequestSchedulerTest2.cpp:102:41:   required fromvoid MyAsyncRequestSchedulerT<T, ReqContextT>::start(std::unique_ptr<SchedulePolicy>, ReqContextT&& ...) [with T = int; ReqContextT = {AsyncContext&}]’
test/dt_tests/AsyncRequestSchedulerTest2.cpp:120:61:   required from here
/usr/include/c++/7.3.0/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >, std::__tuple_element_t<1, std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >, std::__tuple_element_t<2, std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >)’
    -> decltype(std::__invoke(_S_declval<_Ind>()...))
                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7.3.0/tuple:41:0,
                 from /usr/include/c++/7.3.0/bits/unique_ptr.h:37,
                 from /usr/include/c++/7.3.0/memory:80,
                 from /googletest/googletest/include/gtest/gtest.h:54,
                 from test/dt_tests/AsyncRequestSchedulerTest2.cpp:5:
/usr/include/c++/7.3.0/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
     __invoke(_Callable&& __fn, _Args&&... __args)
     ^~~~~~~~
/usr/include/c++/7.3.0/bits/invoke.h:89:5: note:   template argument deduction/substitution failed:
/usr/include/c++/7.3.0/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&); _Args = {MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext}]’:
/usr/include/c++/7.3.0/thread:233:29:   required by substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2}]’
/usr/include/c++/7.3.0/thread:240:2:   required from ‘struct std::thread::_Invoker<std::tuple<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext> >’
/usr/include/c++/7.3.0/thread:127:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&); _Args = {MyAsyncRequestSchedulerT<int, AsyncContext&>&, AsyncContext&}]’
test/dt_tests/AsyncRequestSchedulerTest2.cpp:102:41:   required fromvoid MyAsyncRequestSchedulerT<T, ReqContextT>::start(std::unique_ptr<SchedulePolicy>, ReqContextT&& ...) [with T = int; ReqContextT = {AsyncContext&}]’
test/dt_tests/AsyncRequestSchedulerTest2.cpp:120:61:   required from here
/usr/include/c++/7.3.0/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_result<void (MyAsyncRequestSchedulerT<int, AsyncContext&>::*)(AsyncContext&), MyAsyncRequestSchedulerT<int, AsyncContext&>, AsyncContext>’
make[2]: *** [test/dt_tests/CMakeFiles/AsyncRequestSchedulerTest2.dir/build.make:63: test/dt_tests/CMakeFiles/AsyncRequestSchedulerTest2.dir/AsyncRequestSchedulerTest2.cpp.o] Error 1
make[2]: Leaving directory 'build'
make[1]: *** [CMakeFiles/Makefile2:4765: test/dt_tests/CMakeFiles/AsyncRequestSchedulerTest2.dir/all] Error 2
make[1]: Leaving directory 'build'
make: *** [Makefile:84: all] Error 2
  • 写回答

4条回答 默认 最新

  • GISer Liu 2024-07-12 20:48
    关注

    该回答引用自GPT-3.5, 由博主 GISer Liu 编写:

    问题分析

    用户遇到的编译错误主要是因为在GCC 7.3.0下编译时,std::thread无法正确处理成员函数指针和对象的组合。具体来说,std::thread在处理成员函数指针时需要一个指向对象的指针或引用,而在当前代码中,std::thread的构造函数无法正确推导出类型。

    解决方案

    为了解决这个问题,我们需要确保std::thread能够正确地处理成员函数指针和对象的组合。可以通过以下几种方法来解决:

    1. 使用std::bindlambda表达式:将成员函数和对象绑定在一起,确保std::thread能够正确处理。
    2. **使用std::ref**:将对象引用传递给std::thread,确保引用传递正确。

    具体修改方法

    方法一:使用std::bind

    #include <iostream>
    #include <thread>
    #include <vector>
    #include <memory>
    #include <functional> // 添加此头文件以使用std::bind
    
    template<class T, class... ReqContextT>
    class AsyncRequestSchedulerT2 final {
    public:
        void start(std::unique_ptr<MyClass1> c, ReqContextT&& ...reqContext)
        {
            using AsyncRequestScheduler = AsyncRequestSchedulerT2<T, ReqContextT...>;
            if (c != nullptr) {
                std::vector<std::thread> threads(c->count());
                for (std::size_t pos = 1; pos < c->count(); pos++) {
                    threads[pos - 1] = std::thread(std::bind(&AsyncRequestScheduler::processRequest, this, std::forward<ReqContextT>(reqContext)...));
                }
                for (std::size_t pos = 0; pos < threads.size(); pos++) {
                    threads[pos].join();
                }
            }
            processRequest(std::forward<ReqContextT>(reqContext)...);
        }
    
        void processRequest(ReqContextT&& ...reqContext)
        {
            std::cout << "processRequest" << std::endl;
        }
    };
    

    方法二:使用lambda表达式

    #include <iostream>
    #include <thread>
    #include <vector>
    #include <memory>
    
    template<class T, class... ReqContextT>
    class AsyncRequestSchedulerT2 final {
    public:
        void start(std::unique_ptr<MyClass1> c, ReqContextT&& ...reqContext)
        {
            using AsyncRequestScheduler = AsyncRequestSchedulerT2<T, ReqContextT...>;
            if (c != nullptr) {
                std::vector<std::thread> threads(c->count());
                for (std::size_t pos = 1; pos < c->count(); pos++) {
                    threads[pos - 1] = std::thread([this, &reqContext...]() {
                        this->processRequest(std::forward<ReqContextT>(reqContext)...);
                    });
                }
                for (std::size_t pos = 0; pos < threads.size(); pos++) {
                    threads[pos].join();
                }
            }
            processRequest(std::forward<ReqContextT>(reqContext)...);
        }
    
        void processRequest(ReqContextT&& ...reqContext)
        {
            std::cout << "processRequest" << std::endl;
        }
    };
    

    解释

    1. **使用std::bind**:

      • std::bind将成员函数指针和对象绑定在一起,形成一个可调用对象,这样std::thread可以直接使用这个可调用对象。
      • 需要包含<functional>头文件。
    2. 使用lambda表达式

      • lambda表达式捕获this指针和参数,形成一个可调用对象,这样std::thread可以直接使用这个可调用对象。
      • 代码更加简洁和直观。

    总结

    通过使用std::bindlambda表达式,可以确保std::thread能够正确处理成员函数指针和对象的组合,从而解决在GCC 7.3.0下的编译错误问题。这两种方法都可以有效地解决这个问题,选择其中一种即可。

    如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

    评论

报告相同问题?

问题事件

  • 创建了问题 7月12日

悬赏问题

  • ¥20 有偿:在ubuntu上安装arduino以及其常用库文件。
  • ¥15 请问用arcgis处理一些数据和图形,通常里面有一个根据点划泰森多边形的命令,直接划的弊端是只能执行一个完整的边界,但是我们有时候会用到需要在有很多边界内利用点来执行划泰森多边形的命令
  • ¥30 在wave2foam中执行setWaveField时遇到了如下的浮点异常问题,请问该如何解决呢?
  • ¥20 看图片)删除这个自动化录屏脚本就一直报错找不到脚本文件,如何解决?(相关搜索:bat文件)
  • ¥750 关于一道数论方面的问题,求解答!(关键词-数学方法)
  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件