std:任何抛出异常解析函数类型



我在解析 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(事件函数) 是类型

void (&)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) 0x0000000100012540

这似乎我几乎接近 std::any 存储在里面的东西,但仍然错过了一些我不明白的东西!如何解决此标准::any_cast不匹配?

首先,如果您不需要使用MMM中提供的参数并覆盖它们,则会隐藏一个错误,您将错误的参数发送到MMM。我建议向MMM提供所需的内容,以便它可以制作正确的参数集。


您的函数MMMAAA都通过转发引用接收函数。为了使调用正确解析,它会解析为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) { /* ... */ }

最新更新