我无法将 lambda 作为 std: : 函数传递

让我们关注这个例子:

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 实现它。

62852 次浏览

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

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

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

此外,函数的类型应该匹配。也就是说,它应该接受字符串引用。

这是因为 lambda 函数不是 std::function<...>

auto lambda = [](const std::string& s) { return std::stoi(s); };

不是 std::function<int(const std::string&)>,而是一些未指定的,可以分配给 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); };

,更改您的 member-function 以通过值或常量引用获取函数,或者将函数参数设置为模板类型。如果你传递的是 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
}
};