【问题标题】:std::thread::thread attempting to reference a deleted functionstd::thread::thread 试图引用已删除的函数
【发布时间】:2015-10-02 10:56:09
【问题描述】:

我已经实现了一个非常基础的 ParallelFor 算法,如下所示:

inline void ParallelFor( const size_t startIdx, const size_t endIdx, std::function< void( size_t ) >&& fn, const size_t numThreads = std::thread::hardware_concurrency() )
{
    const size_t portion = std::max( 1, (endIdx - startIdx) / numThreads );
    std::vector< std::thread > threads;
    for ( size_t i = startIdx; i < endIdx; i += portion )
    {
        int from    = i;
        int to      = (i + portion) <= endIdx ? (i + portion) : endIdx;

        threads.push_back( std::thread( [=,&fn]() 
            {
                for ( int j = from; j < to; ++j )
                    fn( j );
            } ) );
    }
    std::for_each( threads.begin(), threads.end(), []( std::thread& x ) 
        { 
            x.join();
        } );
}

但是,当我构建它时,它说 threads.push_back 函数正在“尝试引用已删除的函数”。

我不明白我做错了什么。有人能指出我哪里出错了吗?

编辑:编译器是 VStudio 2015

还有很多错误如下:

1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(657): error C2280: 'std::thread::thread(const std::thread &)': attempting to reference a deleted function
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thread(73): note: see declaration of 'std::thread::thread'
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(775): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,const std::thread&>(_Objty *,const std::thread &)' being compiled
1>          with
1>          [
1>              _Ty=std::thread,
1>              _Objty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(775): note: see reference to function template instantiation 'void std::allocator<_Ty>::construct<_Objty,const std::thread&>(_Objty *,const std::thread &)' being compiled
1>          with
1>          [
1>              _Ty=std::thread,
1>              _Objty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(920): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,const std::thread&>(std::allocator<_Ty> &,_Objty *,const std::thread &)' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::thread>,
1>              _Ty=std::thread,
1>              _Objty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0(920): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,const std::thread&>(std::allocator<_Ty> &,_Objty *,const std::thread &)' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::thread>,
1>              _Ty=std::thread,
1>              _Objty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory(379): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<std::thread,const std::thread&>(_Ty *,const std::thread &)' being compiled
1>          with
1>          [
1>              _Ty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory(379): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Ty>>::construct<std::thread,const std::thread&>(_Ty *,const std::thread &)' being compiled
1>          with
1>          [
1>              _Ty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory(416): note: see reference to function template instantiation '_FwdIt std::_Uninit_copy<_InIt,_FwdIt,std::allocator<_Ty>>(_InIt,_InIt,_FwdIt,std::_Wrap_alloc<std::allocator<_Ty>> &,std::_Nonscalar_ptr_iterator_tag)' being compiled
1>          with
1>          [
1>              _FwdIt=std::thread *,
1>              _InIt=const std::thread *,
1>              _Ty=std::thread
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory(427): note: see reference to function template instantiation '_FwdIt std::_Uninit_copy<const std::thread*,_Iter,_Alloc>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
1>          with
1>          [
1>              _FwdIt=std::thread *,
1>              _Iter=std::thread *,
1>              _Alloc=std::_Wrap_alloc<std::allocator<std::thread>>,
1>              _InIt=const std::thread *
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(1672): note: see reference to function template instantiation '_FwdIt std::_Uninitialized_copy<_Iter,std::thread*,std::_Wrap_alloc<std::allocator<_Ty>>>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
1>          with
1>          [
1>              _FwdIt=std::thread *,
1>              _Iter=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::thread>>>,
1>              _Ty=std::thread,
1>              _InIt=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::thread>>>,
1>              _Alloc=std::_Wrap_alloc<std::allocator<std::thread>>
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(751): note: see reference to function template instantiation 'std::thread *std::vector<std::thread,std::allocator<_Ty>>::_Ucopy<std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::thread>>>>(_Iter,_Iter,std::thread *)' being compiled
1>          with
1>          [
1>              _Ty=std::thread,
1>              _Iter=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::thread>>>
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(751): note: see reference to function template instantiation 'std::thread *std::vector<std::thread,std::allocator<_Ty>>::_Ucopy<std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::thread>>>>(_Iter,_Iter,std::thread *)' being compiled
1>          with
1>          [
1>              _Ty=std::thread,
1>              _Iter=std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<std::thread>>>
1>          ]
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector(742): note: while compiling class template member function 'std::vector<std::thread,std::allocator<_Ty>>::vector(const std::vector<_Ty,std::allocator<_Ty>> &)'
1>          with
1>          [
1>              _Ty=std::thread
1>          ]

【问题讨论】:

标签: c++ multithreading c++11 compiler-errors


【解决方案1】:

我不能立即看到问题,因为它在 gcc 上的工作原理。我怀疑编译器没有调用正确的 push_back 重载。

我会尝试使用 emplace back。

  threads.emplace_back(  [=,&fn]() 
             {
                for ( int j = from; j < to; ++j )
                    fn( j );
             }  );

编辑:由于显然编译器也不支持 emplace,我可能会退回到std::vector&lt;std::shared_ptr&lt;std::thread&gt; &gt;,并将插入代码更改为

  threads.emplace_back( std::make_shared<std::thread>( [=,&fn]() 
             {
                for ( int j = from; j < to; ++j )
                    fn( j );
             }  ) );

连接循环也必须有所改变。

【讨论】:

  • @DaveS:是的,这是处理它的一种方式......真烦人。感谢您的帮助!
  • 所以我只是测试了@Goz 在上面所做的非常基本的情况,简单的 lambda 进入线程构造函数,然后 push_back 临时。那行得通
猜你喜欢
  • 2014-01-10
  • 1970-01-01
  • 2015-05-25
  • 2022-01-22
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
相关资源
最近更新 更多