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 &lt;&lt; v &lt;&lt; "\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 ++ 11 lambda作为成员变量?

奇怪的指针行为 C++ / 继承

C++14:以通用 std::function 作为类成员的通用 lambda

如何使用 C++ lambda 将成员函数指针转换为普通函数指针以用作回调

具有 VARIANT 成员的 VC++ 类对象具有奇怪的行为

使用 C++ 类成员函数作为 C 回调函数