首页 > 解决方案 > 使用其类型而不是其实例调用无捕获

问题描述

我有一个代码,我可以在其中拥有 lambda 的类型,但不是它的实例,我想调用它

我尝试了以下,显然,它不起作用,因为operator()它不是静态成员函数......

#include <utility>

template<typename F, typename ...Args>
void call(F, Args&&... args) {
    &F::operator()(std::forward<Args>(args)...);
}

int main() {
    auto is_odd = [](auto x) {return x % 2 == 1;};
    call(is_odd, 5);
}

我还尝试使用以下方法将其转换为函数指针:

template<typename F, typename ...Args>
void call(F, Args&&... args) {
using return_type = decltype(std::declval<F>()(std::declval<Args&&>()...));
    using ptr = return_type(*)(Args...);
    ptr f = static_cast<ptr>(&F::operator());
    f(std::forward<Args>()...);
}

但它也不起作用。有可能做这样的事情吗?

标签: c++c++17

解决方案


在您的示例中,您确实有一个实例。你将它传递给你的函数,只是参数没有命名。修复很简单:命名参数并使用它:

template<typename F, typename ...Args>
void call(F f, Args&&... args) {
    f(std::forward<Args>(args)...);
}
    
int main() {
    auto is_odd = [](auto x) {return x % 2 == 1;};
    call(is_odd, 5);
}

如果出于某种原因您确实处于没有实例的上下文中,那么除非您可以使用 C++20,否则您将不走运。在 C++20 之前,lambda 不是默认可构造的,因此您无法从它的类型创建实例。使用 C++20,您可以:


template <typename F, typename... Args>
void call(Args&&... args)
{
    F{}(std::forward<Args>(args)...);
}

int main()
{
    auto is_odd = [](auto x) { return x % 2 == 1; };
    call<decltype(is_odd)>(5);
}

推荐阅读