提问人:David Carpenter 提问时间:9/3/2022 更新时间:9/3/2022 访问量:85
使用 lambda 表达式复制和移动构造函数的 C++
C++ copy and move constructors with lambda expressions
问:
我在使用 C++ 复制和移动构造函数时遇到了一些奇怪的东西,在这里,当传递给 lambda 表达式时,复制和移动构造函数都会被执行。奇怪的是,当我将 lambda 的声明类型更改为或使用该函数时,我得到了预期的行为(仅限复制构造)。有谁明白这是为什么?(使用 clang 和 gcc 测试,而不是 msvc)auto
regular_test
#include <iostream>
#include <iomanip>
#include <functional>
using namespace std;
struct Test {
inline Test() {
cout << setw(20) << "constructor ";
PrintAddress();
}
Test(const Test&) {
cout << setw(20) << "copy constructor ";
PrintAddress();
}
Test& operator=(const Test&) {
cout << setw(20) << "copy assignment ";
PrintAddress();
return *this;
}
Test(Test&& other) {
cout << setw(20) << "move constructor ";
PrintAddress();
}
Test& operator=(Test&&) {
cout << setw(20) << "move assignment ";
PrintAddress();
return *this;
}
virtual ~Test() {
cout << setw(20) << "destructor ";
PrintAddress();
}
void PrintAddress() {
cout << "Test&: " << this << endl;
}
};
Test regular_test (Test t) {
cout << "regular_test" << endl;
return t;
}
int main() {
cout << "start" << endl;
function<Test(Test)> lambda_test = [] (Test t) {
cout << "lambda_test" << endl;
return t;
};
Test t;
lambda_test(t);
//regular_test(t);
cout << "done" << endl;
return 0;
}
start
constructor Test&: 0x7fffef6faf28
copy constructor Test&: 0x7fffef6faf08
move constructor Test&: 0x7fffef6fade8
lambda_test
move constructor Test&: 0x7fffef6faf10
destructor Test&: 0x7fffef6fade8
destructor Test&: 0x7fffef6faf10
destructor Test&: 0x7fffef6faf08
done
destructor Test&: 0x7fffef6faf28
答:
1赞
apple apple
9/3/2022
#1
因为 std::function::operator()
是基于类的模板类型定义的。
R operator()( Args... args ) const; // Args are parameter of the *class*
所以会有 ,它会自己制作一个副本,然后转发到 (移动)std::function<Test(Test)>
Test operator()(Test)
lambda_test
评论
0赞
David Carpenter
9/4/2022
好的,但为什么要改变来解决问题呢?function<Test(Test)> lambda_test
auto lambda_test
0赞
apple apple
9/4/2022
@DavidCarpenter,因为 auto 不会添加另一个包装器。(Lambda 甚至没有被复制)
评论
function<Test(Test&)>