我正在尝试结合std::bind
来std::unique_ptr
个类函数,但要使其正常工作会遇到很多麻烦
首先我有两个课
class simpleClass{
public:
simpleClass(int x){
this->simpleNumber = x;
}
int simpleNumber;
simpleClass(const simpleClass &toBeClone){
this->simpleNumber = toBeClone.simpleNumber;
}
simpleClass clone(){
simpleClass *cloned = new simpleClass(*this);
return *cloned;
}
};
class className{
public:
className(doube input){
this->someVariable = input;
}
void someFunction(std::vector<double> x, double c, std::unique_ptr<simpleClass> &inputClass, std::vector<double> &output){
std::vector<double> tempOutput;
for(int i = 0; i<x.size(); i++){
tempOutput.push_back(x[i] + c * this->someVariable + inputClass->simpleNumber);
}
output = tempOutput;
}
double someVariable;
className(const className &toBeClone){
this->someVariable = toBeClone.someVariable;
}
className clone(){
className *cloned = new className(*this);
return *cloned;
}
};
它们都是一些标准类,但是我还实现了一个克隆函数来复制已初始化的类。克隆时,我需要确保原始类和克隆的类指向不同的地址。因此,我使用std::unique_ptr
来确保这一点。
这是主要功能,它也显示了我如何“克隆”
int main(){
className testSubject(5);
std::vector<std::unique_ptr<className>> lotsOfTestSubject;
simpleClass easyClass(1);
std::vector<std::unique_ptr<simpleClass>> manyEasyClass;
for(int i = 0; i<10; i++){
std::unique_ptr<className> tempClass(new className(testSubject.clone()))
lotsOfTestSubject.push_back(std::move(tempClass));
std::unique_ptr<simpleClass> tempEasyClass(new simpleClass(easyClass.clone()))
manyEasyClass.push_back(std::move(tempEasyClass));
}
std::vector<std::vector<<double>> X; //already loaded with numbers
double C = 2;
std::vector<std::vector<<double>> OUT;
for(int i = 0; i<10; i++){
std::vector<double> tempOUT;
lotsOfTestSubject[i]->someFunction(X[i], C, manyEasyClass[i], tempOUT);
OUT.push_back(tempOUT);
//Here if I want to bind
/*
std::bind(&className::someFunction, lotsOfTestSubject[i], X[i], C, manyEasyClass[i], tempOUT);
*/
}
return 0;
}
我之所以“克隆”是因为simpleClass
和className
都需要花很多时间来构造我的实现,而我需要很多。而且由于其中许多将使用相同的参数进行初始化,所以我认为这是最简单的方法。
上面的代码有效,但是我正在尝试提高循环速度。下一行是大部分计算发生的地方。
lotsOfTestSubject[i]->someFunction(X[i], C, manyEasyClass[i], tempOUT);
因此,我正在尝试使用线程来委派工作,据我所知,我需要首先std::bind
。所以我尝试了
std::bind(&className::someFunction, lotsOfTestSubject[i], X[i], C, manyEasyClass[i], tempOUT);
但是编译器会打印出这样的错误
/usr/include/c++/5/tuple|206| recursively required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 1ul; _Head = std::vector<double>; _Tail = {double, std::unique_ptr<simpleClass, std::default_delete<simpleClass> >, std::unique_ptr<simpleClass, std::default_delete<simpleClass> >, std::vector<double>}]’|
/usr/include/c++/5/tuple|108|error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = className; _Dp = std::default_delete<className>]’|
我不知道这是什么意思,因为我刚开始自学c ++。非常感谢任何反馈和指导。 我正在使用c ++ 11和g ++(Ubuntu 5.4.0-6ubuntu1〜16.04.11)5.4.0 20160609
更新
感谢@ rafix07,尝试了您的解决方案,它正常工作。但后来我尝试做
auto theBinded = std::bind(&className::someFunction, &lotsOfTestSubject[i],
X[i], C, std::ref(manyEasyClass[i]), tempOUT);
std::thread testThread(theBinded);
,最终想testThread.join()
但是编译器说
error: pointer to member type ‘void (className::)(std::vector<double>, double, std::unique_ptr<simpleClass>&, std::vector<double>&)’ incompatible with object type ‘std::unique_ptr<className>’|
@kmdreko谢谢您指出!我还没有注意到内存泄漏,但是我会修复。我只用这个吗?
std::unique_ptr<className> tempClass = new className(testSubject);
答案 0 :(得分:1)
编辑
如果要对存储在someFunction
中的实例调用lotsOfTestSubject
,则需要将指针传递到将在其上调用此方法的className
对象,因此下面的行
std::bind(&className::someFunction, lotsOfTestSubject[i]
应替换为:
auto theBinded = std::bind(&className::someFunction, lotsOfTestSubject[i].get(),
^^^
第二个更改是使用std::ref
传递unique_ptr
的{{1}}的原始实例,而不是其副本。 manyEasyClass
总是复制或移动其参数(see reference),但是std::bind
是不可复制的,这就是编译失败的原因。
所以固定线看起来:
unique_ptr
auto theBinded = std::bind(&className::someFunction, lotsOfTestSubject[i].get(),
X[i], C, std::ref(manyEasyClass[i]), std::ref(tempOUT));
也必须由tempOUT
传递,因为您想在std::ref
创建的函子上通过调用operator()来修改此向量。