我不能将 lambda 作为 std::function 传递

Posted

技术标签:

【中文标题】我不能将 lambda 作为 std::function 传递【英文标题】:I cannot pass lambda as std::function 【发布时间】:2016-07-02 00:46:52 【问题描述】:

让我们专注于这个例子:

template<typename T>
class C
    public:
    void func(std::vector<T>& vec, std::function<T( const std::string)>& f)
        //Do Something
    
;

现在,我正在尝试:

std::vector<int> vec;
auto lambda = [](const std::string& s)  return std::stoi(s); ;
C<int> c;
c.func(vec, lambda);

它会导致错误:

no matching function for call to ‘C<int>::func(std::vector<int, std::allocator<int> >&, main()::<lambda(const string&)>&)’
     ref.parse(vec, lambda);

请解释一下什么是不正确的以及如何使用 std::bind 来实现它。

【问题讨论】:

请贴出真正问题旁边正确的代码 【参考方案1】:

这是因为 lambda 函数不是 std::function&lt;...&gt;

的类型
auto lambda = [](const std::string& s)  return std::stoi(s); ;

不是std::function&lt;int(const std::string&amp;)&gt;,而是可以分配给std::function的未指定的东西。现在,当您调用您的方法时,编译器会抱怨类型不匹配,因为转换意味着创建一个无法绑定到非常量引用的临时对象。

这也不是特定于 lambda 函数,因为当您传递一个普通函数时会发生错误。这也不起作用:

int f(std::string const&) return 0;

int main()

    std::vector<int> vec;
    C<int> c;
    c.func(vec, f);

您可以将 lambda 分配给 std::function

std::function<int(const std::string&)> lambda = [](const std::string& s)  return std::stoi(s); ;

,更改您的成员函数以通过值或常量引用获取函数或使函数参数成为模板类型。如果您传递 lambda 或普通函数指针,这将稍微更有效,但我个人喜欢签名中富有表现力的 std::function 类型。

template<typename T>
class C
    public:
    void func(std::vector<T>& vec, std::function<T( const std::string)> f)
        //Do Something
    

    // or
    void func(std::vector<T>& vec, std::function<T( const std::string)> const& f)
        //Do Something
    

    // or
    template<typename F> func(std::vector<T>& vec, F f)
        //Do Something
    
;

【讨论】:

【参考方案2】:

这是因为参数 (std::function) 是一个引用。应该是:

void func(std::vector<T>& vec, std::function<T(const std::string&)> f)
                                                                ^  ^
                                                                   |
                                                                   f not a reference

这样参数就可以转换为参数类型了。

另外,函数的类型应该匹配。 IE。它应该接受一个字符串引用。

【讨论】:

@HumamHelfawi 没有,it does. @AntonSavin 我原来的帖子没有。此后我进行了正确的编辑。 @HumamHelfawi 我没有参考。 @bolov 哦!您强调 std::string 上的 & 这不是问题,所以我没有注意到其他 .. 抱歉 +1

以上是关于我不能将 lambda 作为 std::function 传递的主要内容,如果未能解决你的问题,请参考以下文章

将 lambda 作为块传递

Kotlin函数 ⑦ ( 内联函数 | Lambda 表达式弊端 | “ 内联 “ 机制避免内存开销 - 将使用 Lambda 表达式作为参数的函数定义为内联函数 | 内联函数本质 - 宏替换 )

为啥我不能将 lambda 传递给这个需要 std::function 的函数? [复制]

为啥要将一个类作为 lambda 传递?

将 lambda 函数作为第三个参数传递给 QObject::connect 时出错

将 lambda 作为模板参数传递给函数指针函数模板化