Ral*_*zky 56 c++ lambda bind c++14
在C++ 11之前我使用过boost::bind或者boost::lambda很多.该bind部分使其成为标准库(std::bind),另一部分成为核心语言(C++ lambdas)的一部分,并使lambdas的使用变得更加容易.如今,我几乎没用std::bind,因为我几乎可以用C++ lambdas做任何事情.std::bind我可以想到一个有效的用例:
struct foo
{
template < typename A, typename B >
void operator()(A a, B b)
{
cout << a << ' ' << b;
}
};
auto f = bind(foo(), _1, _2);
f( "test", 1.2f ); // will print "test 1.2"
Run Code Online (Sandbox Code Playgroud)
相当于C++ 14的等价物
auto f = []( auto a, auto b ){ cout << a << ' ' << b; }
f( "test", 1.2f ); // will print "test 1.2"
Run Code Online (Sandbox Code Playgroud)
Much shorter and more concise. (In C++11 this does not work yet because of the auto parameters.) Is there any other valid use case for std::bind beating the C++ lambdas alternative or is std::bind superfluous with C++14?
Ber*_*rtR 65
斯科特迈耶斯谈到了这一点.这是我记得的:
在C++ 14中,没有什么有用的绑定可以做到,也不能用lambdas完成.
但是在C++ 11中,有些事情不能用lambdas完成:
在创建lambdas时捕获时无法移动变量.变量总是被捕获为左值.对于绑定,您可以写:
auto f1 = std::bind(f, 42, _1, std::move(v));
Run Code Online (Sandbox Code Playgroud)表达式无法捕获,只有标识符才能捕获.对于绑定,您可以写:
auto f1 = std::bind(f, 42, _1, a + b);
Run Code Online (Sandbox Code Playgroud)重载函数对象的参数.问题中已经提到过这一点.
在C++ 14中所有这些都是可能的.
移动示例:
auto f1 = [v = std::move(v)](auto arg) { f(42, arg, std::move(v)); };
Run Code Online (Sandbox Code Playgroud)表达示例:
auto f1 = [sum = a + b](auto arg) { f(42, arg, sum); };
Run Code Online (Sandbox Code Playgroud)看问题
完美转发:你可以写
auto f1 = [=](auto&& arg) { f(42, std::forward<decltype(arg)>(arg)); };
Run Code Online (Sandbox Code Playgroud)绑定的一些缺点:
绑定按名称绑定,因此如果您有多个具有相同名称的函数(重载函数),bind不知道使用哪个函数.以下示例将不会编译,而lambdas不会有问题:
void f(int); void f(char); auto f1 = std::bind(f, _1, 42);
Run Code Online (Sandbox Code Playgroud)另一方面,lambda理论上可能会产生比bind更多的模板代码.因为对于每个lambda,你会得到一个独特的类型.对于绑定,只有当你有不同的参数类型和不同的函数时(我想在实践中,你经常不会经常使用相同的参数和函数绑定几次).
Jonathan Wakely在他的回答中提到的实际上是不使用bind的另一个原因.我不明白你为什么要默默地忽略论点.
Jon*_*ely 29
std::bind 仍然可以做多态lambdas不能做的一件事:调用重载函数
struct F {
bool operator()(char, int);
std::string operator()(char, char);
};
auto f = std::bind(F(), 'a', std::placeholders::_1);
bool b = f(1);
std::string s = f('b');
Run Code Online (Sandbox Code Playgroud)
由绑定表达式创建的调用包装器根据您提供的参数调用不同的函数,来自C++ 14多态lambda的闭包可以采用不同类型的参数但不能使用不同数量的参数,并且始终调用(闭合时功能相同的特殊化. 更正:见下面的评论
返回的包装器std::bind也可以用太多的参数调用,它会忽略它们,而由lambda创建的闭包将诊断尝试传递太多参数......但我不认为这是一个好处std::bind:)
有时它只是更少的代码。考虑一下:
bool check(int arg1, int arg2, int arg3)
{
return ....;
}
Run Code Online (Sandbox Code Playgroud)
然后
wait(std::bind(check,a,b,c));
Run Code Online (Sandbox Code Playgroud)
VS 拉姆达
wait([&](){return check(a,b,c);});
Run Code Online (Sandbox Code Playgroud)
我认为与看起来像https://en.wikipedia.org/wiki/Brainfuck的 lambda 相比,这里的 bind 更容易阅读
| 归档时间: |
|
| 查看次数: |
25449 次 |
| 最近记录: |