Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将std::函数包装器转换为可变函数?_C++_C++11_Boost_Variadic Templates - Fatal编程技术网

C++ 如何将std::函数包装器转换为可变函数?

C++ 如何将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

我有这个很好的包装,但我希望它可以接受任意数量的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  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; });