c++ - 标准:任何抛出异常解析函数类型
问题描述
我在从 std::any 解析函数类型时遇到问题。
我基本上是在包装一个函数,它是 lambda 函数中的初始参数,稍后调用它来调用包装的函数,但使用一组新的参数。这就是包装函数的样子。
void Hello(std::string str)
{
LOG(str);
}
我正在尝试像这样完成包装 lambda:我有一个 lambda 函数,它要么执行包装函数,和/或简单地返回包装函数。
template<typename FuncName, typename... FuncArgs>
bool MMM(std::string EventName, FuncName&& EventFunction, FuncArgs&&... Args) noexcept
{
//Storing lambda here
auto fPtr = std::function<std::any(bool)>([=](bool x)
{
if(x){
EventFunction(Args...);
}
return (FuncName)EventFunction;
});
}
现在,当我尝试像这样调用这个 lamdba 时:
template<typename E, typename FuncName, typename... FuncArgs>
bool AAA(E EventName, FuncName &&EventFunction, FuncArgs&&... Args)
{
try {
//resolving lambda and invoking it here
auto func = std::any_cast<decltype(EventFunction)>(fPtr)(false));
func(Args...);
} catch (...) {
std::cout<<"Didn't invoke function: Mismatch argument type.\n";
}
return true;
}
我通过以下方式调用此函数:
MMM(e, Hello, "Hello Florida");
MMM(e, Hello, "Hello USA");
AAA(e, Hello, "Hello World");
问题:当调用函数 AAA 时,我收到一个异常,提示 auto_cast 无法解析函数类型。
在运行时,我看到 (fPtr)(false) 正在返回:
std::__1::function<std::__1::any (bool)> Function = Hello(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)
虽然似乎 decltype(EventFunction) 是类型
void (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) 0x0000000100012540
这似乎我几乎接近 std::any 存储在里面的东西,但仍然错过了一些我不明白的东西!如何解决此 std::any_cast 不匹配问题?
解决方案
首先,如果您不需要使用提供的参数MMM
并覆盖它们,这会隐藏一个错误,您将错误的参数发送到MMM
. 我建议提供所需的东西,MMM
以便它可以制作正确的参数集。
您的函数MMM
和AAA
两者都通过转发引用接收函数。为了正确解析调用,它解析到void(&)(std::string)
哪个是对函数的引用。
然后,在 lambda 中返回该函数:
return (FuncName)EventFunction;
这确实会转换回EventFunction
函数引用,但是返回类型推导会衰减类型,所以它变得等价于:
[](bool) -> void(*)(std::string) { /* ... */ }
然后,你的其他函数做同样的事情。如果我们扩展模板,我们会得到如下所示的内容:
auto func = std::any_cast<void(&)(std::string)>(fPtr)(false));
func(Args...);
但是其中包含的类型std::any
是指向函数的指针,而不是引用。
即使我们修复了返回类型,std::any
也会衰减引用以使其成为函数指针。
解决方案是不通过转发引用接收函数,因为无论如何您都没有转发它:
template<typename E, typename FuncName, typename... FuncArgs>
bool MMM(E EventName, FuncName EventFunction, FuncArgs&&... Args) { /* ... */ }
template<typename E, typename FuncName, typename... FuncArgs>
bool AAA(E EventName, FuncName EventFunction, FuncArgs&&... Args) { /* ... */ }
推荐阅读
- controls - 像提供的示例一样向前或向后播放 vimeo 视频
- batch-file - 嵌套 FOR 循环和 IF 条件的问题
- django - 在前端添加一个图像字段和音频字段。使用 Django 后端和 reactjs 前端
- r - R markdown 为在 R 脚本和其他代码块中运行良好的代码块返回错误
- python - python selenium将文本字段中的值增加到x
- r - R包RSiena,同时适用于多个网络
- ruby-on-rails - 如何更新 Ruby On Rails 应用程序代码 aws ec2 实例
- amazon-web-services - 浏览器缓存从 AWS 无服务器图像处理程序提供的图像
- javascript - XMLHTTPRequest / CORS?,服务器总是在标头上收到“Origin:null”
- authentication - Auth::user() 在用户登录时返回 null 但在刀片模板中工作