2016-10-27 7 views
1

VS2013을 사용하고 있는데 람다가 포함 된 클래스의 인스턴스를 여러 개 사용할 때 이상한 동작이 발생하고 정적 변수가 포함 된 람다를 발견했습니다. 정적 변수는 공유 된 것처럼 보입니다.C++ lambdas 및 정적 변수의 예상 동작

예제 코드는 매우 아래로 손질 여전히 본질을 캡처 :

class HasLambda 
{ 
public: 
    typedef const char* (*ToCharPtr) (const int&); 
    void Init(ToCharPtr pfnToCharPtr) { 
     m_pfnCharPtrConverter = pfnToCharPtr; 
    } 

    const char* IntToString(int i) { 
     return m_pfnCharPtrConverter(i); 
    } 

    static HasLambda* Make() { 
     HasLambda* pHasLambda = new HasLambda; 
     pHasLambda->Init([] (const int &i) -> const char* { static char buf[ 33 ]; sprintf(buf, "%d", i); return buf; }); 
     return pHasLambda; 
    } 

protected: 
    ToCharPtr m_pfnCharPtrConverter; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HasLambda* a; 
    a = HasLambda::Make(); 

    HasLambda* b; 
    b = HasLambda::Make(); 

    const char* aValue = a->IntToString(7); 
    printf("a: %s\n", aValue); 

    const char* bValue = b->IntToString(42); 
    printf("b: %s\n", bValue); 
    printf("a: %s\n", aValue); 

    return 0; 
} 

내가 얻을 출력은이 : 값이 동일하게 : 나는 두 번째 A가 예상 한 것

a: 7 
b: 42 
a: 42 

첫 번째로. 내가 컴파일러 버그를보고, 또는 내가 람다와 정적 변수가 작동하는 방식을 오해하고 있습니까? 어떤 방식 으로든 람다를 잘못 사용하고 있습니까?

답변

5

람다는 필요한 경우 생성되는 개체가 아니라 클래스의 인라인 정의에 대한 속기입니다. 이

class SomeLambda { 
public: 
    const char* operator() (const int& i) { 
    static char buf[33]; 
    sprintf(buf, "%d", i); 
    return buf; 
    } 
}; 

... 
pHasLambda->Init(SomeLambda()); 

정적 초기화 규칙이 멤버 함수에 대한 정적 모든 기능 수준과 같은 의미를 갖는다 : 귀하의 호출은 위에서 거의 비슷하다. X 그런

auto x = []() { static char buf[99]; use_buf(buf); return buf; }; 
auto y = []() { static char buf[99]; use_buf(buf); return buf; }; 

와 y가 동일한 정의에도 불구하고 별도의 클래스를 다음과 같습니다

는 대신 람다 전 만드는 두 가지 라인이 있다면.

+0

나는 당신이 말하는 것을 얻습니다. – Rodyland

+0

은'SomeLambda'는'HasLambda'의 내부 클래스입니까? 그렇다면 사적인 것 같습니까? –

+1

sfk92fksdf @ Lambdas는 기본적으로 이름이 지정되지 않습니다. 유형을 명명하는 방법은 없으므로 자동 변수 나 객체와 같은 함수를 저장하는 std :: function과 같은 것을 할당하는 것 외에도 많은 작업을 수행 할 수 없습니다. – Charlie