2017-12-06 33 views
0

람다 함수를 사용하고자하는 클래스가 있습니다 (예를 들어 public 멤버의 값을 씁니다). 람다는 표준 : : 함수 객체 위해서 (때문에) 유지된다클래스 멤버로서의 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'; 
} 

나는 :: 벡터 표준 이러한 테스터를 수집하는 다른 클래스있다 :

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

출력에서 ​​람다 함수가 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