acr*_*075 5 c++ templates variadic-templates c++11
我试图找到一种方法来调用许多类成员函数,每个函数都有不同的参数,在调用之前和之后发生某些已知的功能.
这个包装函数是我尝试过的,但是例如对它的最后调用不会编译错误:
'bool Wrapper(Work*,std :: function <bool(Args ...)>,Args && ...)':无法推断'std :: function <bool的模板参数(double,std :: string, Args ...)>'from'std :: _ Bind <true,bool,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;
}
Run Code Online (Sandbox Code Playgroud)
(将前置和后置功能放在步骤中看起来乍一看似乎更为可取,但这是不可取的,因为上面是实际代码的简化示例,并且步骤有多个返回位置,并且没有测试.)
我认为显式模板参数可以使模板解析成为可能.我究竟做错了什么?
或 lambda的返回类型std::bind不是,并且从它们构造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;
}
Run Code Online (Sandbox Code Playgroud)
在 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;
}
Run Code Online (Sandbox Code Playgroud)
示例:http ://coliru.stacked-crooked.com/a/2cd3b3e2a4abfcdc
| 归档时间: |
|
| 查看次数: |
1118 次 |
| 最近记录: |