我试图找到一种方法来调用多个类成员函数,每个函数都有不同的参数,并且在调用之前和之后都会发生某些已知的功能。
这个包装函数是我尝试过的,但是例如最后调用它并没有编译错误:
' bool Wrapper(Work *,std :: function< bool(Args ...)>,Args&& ...)' : 可以 不推断模板参数 '的std ::功能<布尔(双,的std :: string,参数数量...)>'从 '的std :: _绑定<真,布尔,性病:: _ Pmf_wrap< bool(__ thiscall Work :: * )(double,std :: string),bool,Work,double,std :: string>,Work * const>'
class Work
{
public:
void DoWork(int a, double b, string c);
private:
void Pre() {};
void Post() {};
bool Step1() { return true; }
bool Step2(int) { return true; }
bool Step3(double, string) { return true; }
};
template<typename... Args>
bool Wrapper(Work *work, std::function<bool(Args...)> func, Args&&... args)
{
work->Pre();
bool ret = func(std::forward<Args>(args)...);
work->Post();
return ret;
}
void Work::DoWork(int a, double b, string c)
{
if (!Wrapper<>(this, std::bind(&Work::Step1, this))) // error
return;
if (!Wrapper<int>(this, std::bind(&Work::Step2, this), a)) // error
return;
if (!Wrapper<double, string>(this, std::bind(&Work::Step3, this), b, c)) // error
return;
}
int main()
{
Work work;
work.DoWork(1, 2.0, "three");
return 0;
}
(将预功能和后功能放在步骤中看起来乍一看是可取的,但这是不可取的,因为上面是实际代码的简化示例,并且步骤有多个返回位置,没有测试。)
我认为显式模板参数可以使模板解析成为可能。我做错了什么?
答案 0 :(得分:4)
使用C ++ 11,std::bind
可以替换为lambda,您可以删除包装器的模板:
class Work
{
public:
void DoWork(int a, double b, string c);
private:
void Pre() {};
void Post() {};
bool Step1() { return true; }
bool Step2(int) { return true; }
bool Step3(double, string) { return true; }
friend bool Wrapper(Work *work, std::function<bool()> func);
};
bool Wrapper(Work *work, std::function<bool()> func)
{
work->Pre();
bool ret = func();
work->Post();
return ret;
}
void Work::DoWork(int a, double b, string c)
{
if (!Wrapper(this, [this]() -> bool { return this->Step1(); }))
return;
if (!Wrapper(this, [this, a]() -> bool { return this->Step2(a); }))
return;
if (!Wrapper(this, [this, b, c]() -> bool { return this->Step3(b, c); }))
return;
}
int main()
{
Work work;
work.DoWork(1, 2.0, "three");
return 0;
}
答案 1 :(得分:4)
返回的std::bind
或lambda类型不是std::function
,而std::function
从std::function
构造它们是不明确的。
一种解决方案是允许任何仿函数,不要使用template<typename F, typename... Args>
bool Wrapper(Work &work, F&& func, Args&&... args)
{
work.Pre();
const bool ret = std::forward<F>(func)(std::forward<Args>(args)...);
work.Post();
return ret;
}
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.view
attribute:NSLayoutAttributeLeading
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:0];
[self.view addConstraint:leftConstraint];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:self.view
attribute:NSLayoutAttributeTrailing
relatedBy:0
toItem:self.view
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:0];
[self.view addConstraint:rightConstraint];