我发现以下代码无法编译非常令人困惑
#include <functional>
class Mountain {
public:
Mountain() {}
Mountain(const Mountain&) = delete;
Mountain(Mountain&&) = delete;
~Mountain() {}
};
int main () {
Mountain everest;
// shouldn't the follwing rvalues be semantically equivalent?
int i = ([](const Mountain& c) { return 1; })(everest);
int j = (std::bind([](const Mountain& c) {return 1;},everest))();
return 0;
}
编译错误是:$ g++ -std=c++20 test.cpp -o test
In file included from test.cpp:1:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:486:26: error: no
matching constructor for initialization of 'tuple<Mountain>'
: _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...)
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:788:14: note: in
instantiation of function template specialization 'std::_Bind<(lambda at test.cpp:14:22)
(Mountain)>::_Bind<Mountain &>' requested here
return typename __helper_type::type(std::forward<_Func>(__f),
^
test.cpp:14:17: note: in instantiation of function template specialization 'std::bind<(lambda at
test.cpp:14:22), Mountain &>' requested here
int j = (std::bind([](const Mountain& c) {return 1;}, everest))();
^
...
所以std::bind
偷偷尝试复制everest
即使 lambda 只想引用它。我是在遇到一个没人关心的奇怪边缘情况(例如,总是可以通过 lambda 捕获对 everest
的引用)还是有理由?如果理由是 bind 可以保护我在 everest
之后不调用 lambda被破坏了,是否有一个不安全的绑定(bind)版本不会这样做?
最佳答案
是的, std::bind
的论据将被复制(或移动)。
The arguments to bind are copied or moved, and are never passed by reference unless wrapped in
std::ref
orstd::cref
.
您可以使用
std::cref
(或 std::ref
)代替。例如。int j = (std::bind([](const Mountain& c) {return 1;}, std::cref(everest)))();
// ^^^^^^^^^^ ^
LIVE
关于c++ - std::bind 和/或 std::forward 的语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67601645/