C ++ lambda函数作为类成员:奇怪的行为
Posted
技术标签:
【中文标题】C ++ lambda函数作为类成员:奇怪的行为【英文标题】:C++ lambda function as class member: strange behaviour 【发布时间】:2017-12-06 16:30:50 【问题描述】:我有一个类,我想在其中使用 lambda 函数(例如,只写一个公共成员的值)。 Lambda 保存在 std::function 对象中:
class Tester
public:
Tester() ;
Tester(double val);
~Tester()
//- variable
double v;
//- write v using lambda
std::function<void()> writeV;
//- write v using simple function
void writeVexp();
;
Tester::Tester(double val)
v = val;
writeV = [this]() std::cout << "inside lambda " << v << '\n'; ;
void Tester::writeVexp()
std::cout << "inside simple function " << v << '\n';
我有另一个类在 std::vector 中收集这些测试人员:
class vectorTester
std::vector<Tester> vtst;
double size;
public:
//- default constructor
vectorTester()
//- construct by number of testers
vectorTester(double num);
~vectorTester()
//- write publuc members of all Testers
void useTesterLambda();
void useTesterSimple();
void useTesterVar();
;
vectorTester::vectorTester(double num)
vtst.reserve(num);
size = num;
for (int i = 0; i < num; ++i)
Tester tst (i + 0.365);
vtst.push_back(tst);
void vectorTester::useTesterLambda()
cout << "\n tester's lambda \n";
for (int i = 0; i < size; ++i)
vtst[i].writeV();
void vectorTester::useTesterSimple()
cout << "\n tester's simple function \n";
for (int i = 0; i < size; ++i)
vtst[i].writeVexp();
void vectorTester::useTesterVar()
cout << "\n tester's vars \n";
for (int i = 0; i < size; ++i)
cout << vtst[i].v << endl;
而且主要功能很简单:
int main()
vectorTester vtst(5);
vtst.useTesterLambda();
vtst.useTesterSimple();
vtst.useTesterVar();
return 0;
输出告诉我lambda函数看不到Tester类的值V!
tester's lambda
inside lambda 0
inside lambda 4.94066e-324
inside lambda 9.88131e-324
inside lambda 1.4822e-323
inside lambda 1.97626e-323
tester's simple function
inside simple function 0.365
inside simple function 1.365
inside simple function 2.365
inside simple function 3.365
inside simple function 4.365
tester's vars
0.365
1.365
2.365
3.365
4.365
这种奇怪行为的原因是什么?
【问题讨论】:
如果向量vtst
必须重新分配捕获的this
指针悬空。 Tester
间接包含一个指向它自己的实例的指针,而你已经违反了 3 或 5 的规则。
使用[v]() cout << v << "\n";
。
@qdbp 如果您不想显式刷新流,最好不要使用 endl
@UKMonkey:好的,谢谢
@qdbp 两个编译器错误:捕获非变量Tester::v;此 lambda 函数中未捕获“this”
【参考方案1】:
正如评论中所说,您违反了 0/3/5 的规则,您必须实现复制构造函数
class Tester
public:
Tester(double val) : v(val)
writeV = [this]()std::cout << "inside lambda " << v << '\n';;
Tester(const Tester& rhs) : v(rhs.v)
writeV = [this]()std::cout << "inside lambda " << v << '\n';;
Tester& operator =(const Tester& rhs)
v = rhs.v;
// Keep function
return *this;
void writeVexp() const std::cout << "inside simple function " << v << '\n';
private:
double v;
std::function<void()> writeV;
;
Demo
【讨论】:
以上是关于C ++ lambda函数作为类成员:奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章
C++14:以通用 std::function 作为类成员的通用 lambda
如何使用 C++ lambda 将成员函数指针转换为普通函数指针以用作回调