2017-12-06 7 views
0

ラムダ関数を使用したいクラスがあります(たとえば、publicメンバの値を書きます)。ラムダは、STD ::関数オブジェクトにkeepedさ:クラスメンバーとしてのC++ラムダ関数:奇妙な振る舞い

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にこれらのテスターを収集し、別のクラス::ベクトルがあります。

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

を、main関数は単純です:

int main() 
{ 
    vectorTester vtst(5); 

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

    return 0; 
} 

ラムダ関数が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 

この異常な動作の理由は何ですか?あなたは0/3/5のルールを破ったコメントで述べているように

+1

を実装する必要がthis'ポインタがぶら下がっている。 'Tester'は間接的にそれ自身のインスタンスへのポインタを含み、あなたは3または5のルールを壊しました。 –

+0

' [v](){cout << v << "\ n";} 'を使用します。 – qdbp

+0

@qdbpストリームを明示的にフラッシュしたくない場合は、endlを使用しない方が良いでしょう。 – UKMonkey

答えて

0

は、あなたが持っているvtst`ベクトルが ``キャプチャを再割り当てする場合は、コピーコンストラクタ

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