标签:c c11 variadic-templates boost
我有这个非常好的包装,但我希望它接受任意数量的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;
}
}
我尝试了以下,并一直在谷歌搜索,但男人的错误信息是神秘的 – 我正在努力做甚至可能吗?
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;
}
}
解决方法:
你可以做你想做的事,因为这个简单的程序显示:
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;
}
问题是,一旦RunSafeFn2成为模板,您也可以模拟仿函数本身.当您已经是模板时,键入擦除可调用的内容几乎没有什么好处.所以在实践中,它更有意义:
template <class F, class ... Ts>
void foo(F f, Ts && ... ts) {
f(std::forward<Ts>(ts)...);
}
哪个仍然允许上面的用法,但也允许做:
foo([] (int i) { std::cerr << "hello " << i; }, 5);
由于完全避免创建std :: function对象,因此效率也会更高.要处理返回类型,因为你只限于C 11,你可以这样做:
template <class F, class ... Ts>
auto foo(F f, Ts && ... ts) -> boost::variant<decltype(f(std::forward<Ts>(ts)...)), std::string> {
try {
return f(std::forward<Ts>(ts)...);
}
...
}
编辑:让我添加一个最后的想法:在C 11和on中,callables很容易创建,一个更简单的替代方法实际上是采用可调用且无参数:
template <class F>
auto foo(F f) -> boost::variant<decltype(f()), std::string> {
try {
return f();
}
...
}
那是因为很容易捕捉到你需要的论据.例如,如果我以这种方式编写了我的原始示例,我可以通过执行以下操作来使用它:
int i = 5;
foo([&] () { std::cerr << "hello " << i; });
这有利有弊,特别是在处理移动类型时,但如果您想最大限度地减少维护负担并且您的用例很简单,这是一个合理的选择.
标签:c,c11,variadic-templates,boost 来源: https://codeday.me/bug/20190823/1698859.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。