Home C++ lambda function as class member: strange behaviour
Reply: 1

C++ lambda function as class member: strange behaviour

Darksy
1#
Darksy Published in 2017-12-06 16:30:50Z

I have a class where I would like to use lambda function (for example, just write a value of public member). Lambda is keeped in the std::function object:

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';
}

I have another class which collects these testers in 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;
    }
}

And the main function is simple:

int main()
{
    vectorTester vtst(5);

    vtst.useTesterLambda();
    vtst.useTesterSimple();
    vtst.useTesterVar();

    return 0;
}

The output said me that lambda function can not see the value V of class Tester!

     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

What is the reason of this strange behaviour?

Jarod42
2#
Jarod42 Reply to 2017-12-06 16:58:33Z

As state in comment you have broken rule of 0/3/5, you have to implement copy constructor

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

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.315345 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO