首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

bind回到的函数对象不能拷贝么?

2013-01-18 
bind返回的函数对象不能拷贝么????我自己写了一个多线程的for_each,windows下的。环境VS2008,控制台程序。思

bind返回的函数对象不能拷贝么????
我自己写了一个多线程的for_each,windows下的。环境VS2008,控制台程序。
思路就是获取当前处理器数量,然后创建处理器数量-1个线程。直到所有线程跑完,for_each返回。
但是现在发现这个东西似乎不能支持bind,如果不能支持bind用起来就很麻烦啊。
因为是日文系统,所以报错信息也没啥用。对于报错信息,我的理解是,因为bind没有赋值/拷贝构造函数,所以在构造thread_parameter的时候会找不到复制构造函数。
但是这不科学啊,没有复制构造函数,传值怎么传过来的啊??!!
请大家帮帮忙啊!!
报错如下:
1>main.cpp
1>d:\mydocuments\visual studio 2008\projects\parallel_for_each\parallel_for_each\parallel.h(39) : error C2512: 'std::tr1::_Bind<_Ret,_BindN>' : クラス、構造体、共用体に既定のコンストラクタがありません。
1>        with
1>        [
1>            _Ret=std::tr1::_Notforced,
1>            _BindN=std::tr1::_Bind0<std::tr1::_Callable_obj<void (__cdecl *)(int),false>>
1>        ]
1>        d:\mydocuments\visual studio 2008\projects\parallel_for_each\parallel_for_each\parallel.h(81) : コンパイルされたクラスの テンプレート のインスタンス化 'parallel::thread_parameter<InputIterator,Function>::thread_parameter<InputIterator,Function>(InputIterator,InputIterator,UINT,UINT,Function,HANDLE)' の参照を確認してください
1>        with
1>        [
1>            InputIterator=int *,
1>            Function=std::tr1::_Bind<std::tr1::_Notforced,std::tr1::_Bind0<std::tr1::_Callable_obj<void (__cdecl *)(int),false>>>
1>        ]
1>        d:\mydocuments\visual studio 2008\projects\parallel_for_each\parallel_for_each\main.cpp(24) : コンパイルされたクラスの テンプレート のインスタンス化 'Function parallel::for_each<int*,std::tr1::_Bind<_Ret,_BindN>>(InputIterator,InputIterator,Function)' の参照を確認してください
1>        with
1>        [
1>            Function=std::tr1::_Bind<std::tr1::_Notforced,std::tr1::_Bind0<std::tr1::_Callable_obj<void (__cdecl *)(int),false>>>,
1>            _Ret=std::tr1::_Notforced,
1>            _BindN=std::tr1::_Bind0<std::tr1::_Callable_obj<void (__cdecl *)(int),false>>,
1>            InputIterator=int *
1>        ]
1>ビルドログは "file://d:\myDocuments\Visual Studio 2008\Projects\parallel_for_each\parallel_for_each\Debug\BuildLog.htm" に保存されました。





// main.cpp

#include "parallel.h"

#include <iostream>
#include <functional>

using std::cout;
using std::tr1::bind;
using namespace std::tr1::placeholders;

void print(int i)
{
for(int j = 0 ; j < 1000000 ; ++j)
bool t = true;
//cout << "hello "<< i <<"\n";
}

int main()
{
const unsigned c = 1000;
int ar[c] ;
for(int i = 0 ; i < c ; ++i)


ar[i] = i;
parallel::Initialize();
parallel::for_each(ar,ar+c,bind(print));
return 0;
}




// parallel.h

#include "windows.h"
#include <vector>
#include <string>
#include <cassert>

using std::vector;
using std::wstring;

namespace parallel
{
bool init = false;
UINT CoreCount = 0;
void Initialize()
{
// get system infomation
LPSYSTEM_INFO info = new SYSTEM_INFO;
GetSystemInfo(info);

// cpu number, the cores you see in task manager
CoreCount = info->dwNumberOfProcessors - 1;
if(CoreCount==0)
CoreCount = 1;

init = true;
}

template<class InputIterator, class Function>
class thread_parameter{
public:
InputIterator first;
InputIterator last;
UINT Begin;
UINT StepLength;
Function f;
HANDLE mutex;
thread_parameter(thread_parameter& param){first = param.first;last = param.last;Begin = param.Begin;StepLength = param.StepLength;f = param.f; mutex = param.mutex;};
thread_parameter(){Begin = 0;StepLength = 0;mutex = 0;};
template<class InputIterator, class Function>
thread_parameter(InputIterator fst,InputIterator l,UINT bg,UINT sl,Function func,HANDLE m)
{first = fst; last = l; Begin = bg; StepLength = sl; f = func; mutex = m;};
};
template<class InputIterator, class Function>
DWORD WINAPI thread_function(LPVOID lpParameter)
{
thread_parameter<InputIterator, Function>* param = (thread_parameter<InputIterator, Function>*)(lpParameter);
WaitForSingleObject(param->mutex,INFINITE);
UINT stepCount = 0;
while(param->first != param->last)
{
Function func = param->f;
if(stepCount>=param->Begin && (stepCount-param->Begin)%param->StepLength==0)
{
func(*(param->first));
}
stepCount++;
(param->first)++;
}
ReleaseMutex(param->mutex);
return 0;
}
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
assert(init);
vector<HANDLE> mutexes;
mutexes.reserve(CoreCount);
for(UINT i = 0 ; i < CoreCount ; ++i)
{
// prepare mutex
wchar_t buffer[100];
::swprintf_s(buffer,L"zs@FNST parallel for_each mutex%d",i);
wstring mutexName((wchar_t*)buffer);
mutexes.push_back(CreateMutex(0,false,mutexName.c_str()));
// prepare other parameter
thread_parameter<InputIterator,Function>* param = new thread_parameter<InputIterator,Function>(
first,
last,
i,
CoreCount,
f,
mutexes.back());
CreateThread(0,0,thread_function<InputIterator,Function>,static_cast<void*>(param),0,0);
}

// wait for all the threads to return
for(UINT i = 0 ; i < mutexes.size() ; ++i)


{
WaitForSingleObject(mutexes[i],INFINITE);
}
for(UINT i = 0 ; i < mutexes.size() ; ++i)
{
ReleaseMutex(mutexes[i]);
}
return f;
}
}


[解决办法]
引用:
引用:bind用错了
C/C++ code?123456789void print(int i){}int main(){    bind(print)(12);//编译错误    bind(print,12)();//编译正确    return 0;}那个我发现了,现在是这样的,但是还是不行……
C/C++ code?12345678……


namespace parallel
{
    bool init = false;
    UINT CoreCount = 0;
    void Initialize()
    {
        // get system infomation
        LPSYSTEM_INFO info = new SYSTEM_INFO;
        GetSystemInfo(info);
 
        // cpu number, the cores you see in task manager
        CoreCount = info->dwNumberOfProcessors - 1;
        if(CoreCount==0)
            CoreCount = 1;
 
        init = true;
    }
 
    template<class InputIterator, class Function>
    class thread_parameter{
    public:
        InputIterator first;
        InputIterator last;
        UINT Begin;
        UINT StepLength;
        Function f;
        HANDLE mutex;
        thread_parameter(thread_parameter& param){first = param.first;last = param.last;Begin = param.Begin;StepLength = param.StepLength;f = param.f; mutex = param.mutex;};
        thread_parameter(){Begin = 0;StepLength = 0;mutex = 0;};
        thread_parameter(InputIterator fst,InputIterator l,UINT bg,UINT sl,Function func,HANDLE m):f(func)
        {first = fst; last = l; Begin = bg; StepLength = sl; mutex = m;};
    };
    template<class InputIterator, class Function>
    DWORD WINAPI thread_function(LPVOID lpParameter)
    {
        thread_parameter<InputIterator, Function>* param = (thread_parameter<InputIterator, Function>*)(lpParameter);
        WaitForSingleObject(param->mutex,INFINITE);
        UINT stepCount = 0;

        while(param->first != param->last)


        {
            if(stepCount>=param->Begin && (stepCount-param->Begin)%param->StepLength==0)
            {
                param->f( *(param->first) );
            }
            stepCount++;
            (param->first)++;
        }
        ReleaseMutex(param->mutex);
        return 0;
    }
    template<class InputIterator, class Function>
    Function for_each(InputIterator first, InputIterator last, Function f)
    {
        assert(init);
        vector<HANDLE> mutexes;
        mutexes.reserve(CoreCount);
        for(UINT i = 0 ; i < CoreCount ; ++i)
        {
            // prepare mutex
            wchar_t buffer[100];
            ::swprintf_s(buffer,L"zs@FNST parallel for_each mutex%d",i);
            wstring mutexName((wchar_t*)buffer);
            mutexes.push_back(CreateMutex(0,false,mutexName.c_str()));
            // prepare other parameter
            thread_parameter<InputIterator,Function>* param = new thread_parameter<InputIterator,Function>(
            first,
            last,
            i,
            CoreCount,
            f,
            mutexes.back());
            CreateThread(0,0,thread_function<InputIterator,Function>,static_cast<void*>(param),0,0);
        }
 
        // wait for all the threads to return
        for(UINT i = 0 ; i < mutexes.size() ; ++i)
        {
            WaitForSingleObject(mutexes[i],INFINITE);
        }
        for(UINT i = 0 ; i < mutexes.size() ; ++i)
        {
            ReleaseMutex(mutexes[i]);


        }
        return f;
    }
}


[解决办法]
引用:
引用:引用:引用:bind用错了
C/C++ code?123456789void print(int i){}int main(){    bind(print)(12);//编译错误    bind(print,12)();//编译正确    return 0;}那个我发现……
错误信息是
std::tr1::_Bind<_Ret,_BindN>没有默认构造函数
初始化列表里是初始化所以没问题,赋值形式的话要先默认初始化,因此不行

热点排行