2014-06-13 2 views
5

함수와 펑터를 비교할 때 함수에 대한 펑터의 장점은 펑터가 statefull이라는 점입니다.펑터 멤버의 상태 데이터와 글로벌 함수

그러나이 코드에서는 함수가 statefull이 될 수도 있습니다. 그래서 내가 뭘하고/잘못 이해하고 있니?

struct Accumulator 
{ 
    int counter = 0; 
    int operator()(int i) 
    { 
    counter += i; 
    return counter; 
    } 
}; 

int Accumulate(int i) 
{ 
    static int counter = 0; 
    counter += i; 

    return counter; 
}; 

int main() 
{ 
    Accumulator acc; 
    std::vector<int> vec{1,2,3,4}; 
    Accumulator acc2 = std::for_each(vec.begin(), vec.end(), acc); 
    int d1 = acc(0); // 0, acc is passed by value 
    int d2 = acc2(0); // 10 

    std::for_each(vec.begin(), vec.end(), Accumulate); 
    int d4 = Accumulate(0); // 10 

    return 0; 
} 
+0

어떻게 시작 하시겠습니까? – chris

+0

@ 크리스 : 제발 당신 reformulation 수 있습니까? – Korchkidu

+0

상태에 '정적'을 사용하는 함수로 상태는 모든/모든 사용 및 호출에서 공유됩니다. 사용법에 따라 "재설정"기능이 필요할 수 있습니다. Functor의 경우 많은 것을 독립적으로 만들 수 있습니다. – crashmstr

답변

9

함수의 정적 멤버는 공유되지만 함수기의 각 인스턴스에는 고유 한 상태가 있습니다.

Accumulate() 메서드를 사용하여 for_each을 여러 번 호출하면 카운터가 재설정되지 않고 이후의 각 호출이 이전 호출이 끝난 곳에서 시작됩니다. 펑터는 각 인스턴스가 재사용되는 경우에만이 동작을 수행합니다. 새로운 펑터를 만들면 문제가 해결됩니다.

+0

꽤 명확한 대답! 감사. – Korchkidu

9

당신은 상태를 저장하기 위해 static 지역 변수를 사용했지만, 국가의 단 하나의 사본에 상관없이 Accumulate를 사용하는 횟수가 없습니다. 그리고 chris가 지적했듯이 초기화는 오직 한 번만 수행됩니다.

펑터를 사용하여 만드는 새 펑터 인스턴스는 인스턴스 생성 중에 초기화되는 고유 한 독립 상태를 갖습니다. (예를 들어, 두 번째 기능은 수정할 수 도우미 네임 스페이스에 변수를 이동) 기능 버전의 상태에 대한 재설정 메커니즘을 제공하더라도

, 당신은 여전히 ​​한 번에 하나의 축적이있다.

펑터를 사용하면 "소수가 여기에 누적되고, 심지어 복합체가 있고, 세 개의 누적기를 사용하는 세 번째 복합체가 있습니다"와 같은 규칙을 개발하는 데 아무런 문제가 없습니다.

+1

감사합니다. 훨씬 명확합니다! 댄의 대답을 수락해도 괜찮습니까? 두 대답은 훌륭하지만 더 이상 평판이 필요하지 않습니다 .-D – Korchkidu

+1

@Korchkidu : 좋은 계획 같아요. –