c++ - 将任意 lambda 表达式传递给函数?

标签 c++ templates c++11 lambda

我有一个非常奇怪的问题,因为我正在尝试创建某种编译器... 我想将 lambda 表达式传递给这样的模板函数:

    template<class T>
delegate<T>* bind(std::function<T> func)
{
    return nullptr;
}

这样我就可以打电话了

bind([&](int a) { // do something });

... 所以通常情况下,这不是问题,因为 std::function 能够捕获 lambda。但这里的问题是(让我们假设)我不知道或不想提供关于“T”到底是什么的信息。它可以是您也可以插入到 std::function<>...

中的任何函数签名

我还需要将这个“推断的”签名传递回我想返回的“委托(delegate)”类,并且该委托(delegate)类需要是指向类的指针...

现在我想出了这个:

template<class T>
struct delegate : public std::function<T>
{
    delegate(const std::function<T>& func) : std::function<T>(func) { }
    delegate(const delegate<T>& func) { }
};

template<class T>
delegate<T>* bind(std::function<T>&& func)
{
    return new delegate<T>(std::forward<std::function<T>>(func));
}

但上面调用“绑定(bind)”的示例失败并显示“失败的模板参数推导”。在调用“绑定(bind)”时,我如何才能使它工作而不必明确指定“T”参数(至少它可以工作)?

因为理论上我的编译器有解决这个问题的所有信息,我可以只插入“T”的实例,但这会使生成的代码不必要地复杂化。

顺便说一句,我使用的是最新的 Clang 编译器。


这是最终的解决方案:

    template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> struct get_signature<Ret(Mem::*)(Args...) const> {
    typedef Ret type(Args...);
};

template<class T> 
delegate<typename get_signature<decltype(&T::operator())>::type>* bind(T func)
{
    return nullptr;
}

请注意,您可能需要根据需要调整“const”修饰符。

最佳答案

首先,您完全搞砸了右值引用。您的转发根本不起作用。

其次,在某些情况下这是不可能的。对于某些函数对象,您可以通过将成员函数指针指向operator() 并检查其签名来推断签名.但是对于其他人来说,他们会重载并且不起作用。

template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> 
struct get_signature<Ret(Mem::*)(Args...)> {
    typedef Ret(Args...) type;
};

template<class T> 
delegate<typename get_signature<&T::operator()>::type>* bind(T func)
{
    return nullptr;
}

第三,std::bind?

关于c++ - 将任意 lambda 表达式传递给函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13663381/

相关文章:

C++ 三重等于?

c++ - 使用模板作为参数时的函数模板特化

html - Liferay 7 Freemarker 模板。 staticUtil 已评估为 NULL 或缺失 - 尝试获取 JournalArticle 的类别

c++ - "&"在函数调用中的使用,困惑

c++ - 多级继承错误 "cout does not name a type"

c++ - 编译器如何确定使用哪个函数?

JavaScript 模板

c++ - 在抛出 'std::system_error' 线程池实例后调用终止

c++ - std::tuple 具有通用类型,如 boost::any

c++ - 当我知道类型时,如何避免虚拟调用?