C++ 如何将std::函数包装器转换为可变函数?
我有这个很好的包装,但我希望它可以接受任意数量的T,S,R,QC++ 如何将std::函数包装器转换为可变函数?,c++,c++11,boost,variadic-templates,C++,C++11,Boost,Variadic Templates,我有这个很好的包装,但我希望它可以接受任意数量的T,S,R,Q template<typename U, typename T, typename S> boost::variant<U, std::string> RunSafeFn2(const std::function<U(const T&,const S&)>& f, const std::string& errMsg, const T& a1, const
template<typename U, typename T, typename S>
boost::variant<U, std::string> RunSafeFn2(const std::function<U(const T&,const S&)>& f, const std::string& errMsg, const T& a1, const S& a2)
{
try
{
return f(a1,a2);
}
catch (...)
{
return errMsg;
}
}
模板
boost::variant RunSafeFn2(常量std::function&f,常量std::string&errMsg,常量T&a1,常量S&a2)
{
尝试
{
返回f(a1,a2);
}
捕获(…)
{
返回errMsg;
}
}
我尝试了下面的内容,一直在谷歌上搜索,但这些错误消息是神秘的——我想做的是可能的吗
template<typename U, class ... Ts>
boost::variant<U, std::string> RunSafeFnN(const std::function<U(Ts)>& f, const std::string& errMsg, Ts ... ts)
{
try
{
return bind(f, ts...);
}
catch (...)
{
return errMsg;
}
}
模板
boost::variant RunSafeFnN(const std::function&f,const std::string&errMsg,Ts…Ts)
{
尝试
{
返回绑定(f,ts…);
}
捕获(…)
{
返回errMsg;
}
}
你可以做你想做的事,正如这个简单的程序所示:
template <class ... Ts>
void foo(std::function<void(Ts...)> f, Ts && ... ts) {
f(std::forward<Ts>(ts)...);
}
int main()
{
std::function<void(int)> f = [] (int i) { std::cerr << "hello " << i; };
foo(f, 5);
return 0;
}
这仍然允许使用上述方法,但也允许执行以下操作:
foo([] (int i) { std::cerr << "hello " << i; }, 5);
编辑:让我添加最后一个想法:在C++11及更高版本中,可调用项非常容易创建,一个更简单的替代方法实际上是采用可调用且无参数:
template <class F>
auto foo(F f) -> boost::variant<decltype(f()), std::string> {
try {
return f();
}
...
}
模板
自动foo(F)->boost::variant{
试一试{
返回f();
}
...
}
这是因为它很容易捕捉到你需要的论点。例如,如果我以这种方式编写了我的原始示例,我可以通过以下方式使用它:
int i = 5;
foo([&] () { std::cerr << "hello " << i; });
inti=5;
foo([&](){std::cerr From Clang,我得到错误:声明类型包含未扩展的参数包“Ts”
,在函数中的Ts
下有波形。如果我要判断的话,我会说这相当清楚。当然,但它告诉我怎么做?好吧,bind完全是一个骗局。它用于创建一个可从另一个调用的参数包。但是你我不想创建一个可调用的,你只想调用它。std::forward对于调用这样的可调用函数来说并不是绝对必要的,但出于各种原因,它是最正确的方法。你能在C++14中对返回类型做些更好的事情吗?我们在MSVC 2015上。2是的,你最后的想法是我最初做的,直到人们想要能够编写eir自己的失败包装器包含失败包装器中的参数。@ProbablyAStupidQuestion好吧,请参阅我的更新,它大体上简化了一些事情。实际上,我不确定14中是否有简单的简化;我本来想只使用auto,但后来我意识到这与返回变量不太兼容。这对我来说太难了更优雅,但如果你通过ARG,他们可以做聪明的事情(如根据ARG检查返回)。
template <class F>
auto foo(F f) -> boost::variant<decltype(f()), std::string> {
try {
return f();
}
...
}
int i = 5;
foo([&] () { std::cerr << "hello " << i; });