std :: thread :: thread试图引用已删除的函数

时间:2015-10-02 10:56:09

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

我已经实现了一个非常基础的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>          ]

1 个答案:

答案 0 :(得分:3)

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

我会尝试使用emplace代替。

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

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

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

连接循环也必须有变化。