2011-05-13 5 views
11

양키를 사용하여 데이터에 평균 및 분산을 생성 할 수 있습니다. deque에 n과 n^2를 쌍으로 저장 한 다음 내 연산자 +()를 사용하여 누적을 사용합니다.누적 된 쌍을 사용하여 문제가 발생했습니다.

#include <deque> 
#include <numeric> 
#include <utility> 

template <typename T1, typename T2> 
std::pair<T1,T2> operator+(const std::pair<T1,T2>& lhs, const std::pair<T1,T2>& rhs) 
{ 
    return std::pair<T1,T2>(lhs.first + rhs.first, lhs.second + rhs.second); 
} 

namespace resource 
{ 
template <typename T> 
class rollingStats 
{ 
public: 
    rollingStats(unsigned int n, const T& val): 
     xs(n, std::pair<T,T>(val, val*val)) 
    {;} 
    ~rollingStats() 
    {;} 

    T getMean(void) const 
    { 
     std::pair<T,T> sum = std::accumulate(xs.begin(), xs.end(), std::pair<T,T>((T)0,(T)0)); 
     return sum.first/xs.size(); 
    } 

    T getVar(void) const 
    { 
     const unsigned int n = xs.size(); 

     std::pair<T,T> sum = std::accumulate(xs.begin(), xs.end(), std::pair<T, T > ((T)0,(T)0)); 

     return ((n * sum.second - sum.first*sum.first)/(n * n)); 
    } 

    void addValue(const T& val) 
    { 
     xs.pop_front(); 
     xs.push_back(std::pair<T,T>(val,val*val)); 
    } 

    const std::deque<std::pair<T,T> >& getXs(void) const {return xs;} 
private: 
    std::deque<std::pair<T,T> > xs; 
}; 
} 

해결할 수없는 g ++ 4.1.2를 사용하여 컴파일 오류가 발생합니다.

[ CC   ] resource/UnitTest: rollingStats_Test.o 
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_numeric.h: In function ‘_Tp std::accumulate(_InputIterator, _InputIterator, _Tp) [with _InputIterator = std::_Deque_iterator<std::pair<float, float>, const std::pair<float, float>&, const std::pair<float, float>*>, _Tp = std::pair<float, float>]’: 
../rollingStats.hpp:45: instantiated from ‘T resource::rollingStats<T>::getMean() const [with T = float]’ 
rollingStats_Test.cpp:98: instantiated from here 
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_numeric.h:89: error: no match for ‘operator+’ in ‘__init + __first.std::_Deque_iterator<_Tp, _Ref, _Ptr>::operator* [with _Tp = std::pair<float, float>, _Ref = const std::pair<float, float>&, _Ptr = const std::pair<float, float>*]()’ 
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_bvector.h:267: note: candidates are: std::_Bit_iterator std::operator+(ptrdiff_t, const std::_Bit_iterator&) 
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_bvector.h:353: note:     std::_Bit_const_iterator std::operator+(ptrdiff_t, const std::_Bit_const_iterator&) 
make: *** [rollingStats_Test.o] Error 1 

나는 무엇이 여기에서 잘못 되었습니까? STL에만 의존하는 대신 내 자신의 펑터를 추가해야합니까?

감사

+0

것은 내가이 (가) ['부스트 : accumulators'] (HTTP 사용하는 것이 좋습니다 수 있습니다 : //www.boost.org/doc/libs/1_46_1/doc/html/accumulators.html) library? –

+1

I * think * 당신은 쌍의 + 연산자를 std 네임 스페이스에 넣어야한다고 생각합니다; C++ 네임 스페이스 해석 규칙을 사용하는 것처럼 보입니다. –

+0

http://codepad.org/an0dUFgk.이 컴파일을 처음 만들었습니다. – jkp

답변

12

std::pairoperator+이 없습니다, 당신은 operator+의 구현을 호출하는 std::accumulate 수있는 방법을 제공하지 않았습니다.

난 당신이 펑터에 operator+에서 제공하는 기능을 래핑 할

...

template <typename T1, typename T2> struct pair_sum : public std::binary_function< std::pair<T1,T2>, std::pair<T1,T2>, std::pair<T1,T2> > 
{ 
    std::pair<T1,T2> operator()(const std::pair<T1,T2>& lhs, const std::pair<T1,T2>& rhs) 
    { 
     return std::pair<T1,T2>(lhs.first + rhs.first, lhs.second + rhs.second); 
    } 
}; 

... 그리고 std::accumulate의 버전을 호출하여 그 사 개 인수에 소요되는 사용

std::pair<T,T> sum = std::accumulate(xs.begin(), xs.end(), std::make_pair((T)0,(T)0), pair_sum<T,T>()); 
+0

고마워. 내가 필요한 것. 나는 쌍을 위해 나의 연산자 +를 제공 할 수 있고 그것이 집어 올 것이라고 생각했다. – DanS

+0

이 답변은 내가 감사해야 할 필요가있는 것입니다. – petric

0

을 인용구 : Oliver Seiler 님의 댓글 :

다음과 같은 세 가지 옵션이 있습니다 : add_pai를 사용하여 이진 함수를 사용하는 accumulate 양식 사용 r 함수를 써야합니다 (아마도 가장 간단한 옵션입니다). subclass std :: pair 그리고 더하기 연산자 (더러운 느낌); 쌍이 있거나 그냥 필요한 멤버가있는 새로운 구조체/클래스를 추가하고 쌍 대신 (아마 가장 유연한 옵션)이를 사용하십시오.

[이것은 커뮤니티 위키의 답변입니다. 수정, 샘플을 추가, 편집 주시기 등] 당신은 boost::lambda의 도움으로 쌍 합계를 얻을 수

0

:

#include <boost/lambda/bind.hpp> 
#include <boost/lambda/construct.hpp> 

template<typename T> 
void summarize() 
{ 
    typedef std::pair<T, T> pt_t; 
    std::deque<pt_t> xs; 
    using namespace boost::lambda; 

    // fill xs with useful stuff 

    pt_t res = std::accumulate(
    xs.begin(), xs.end(), std::make_pair(T(),T()), 
    bind(constructor<pt_t>(), 
     bind(std::plus<T>(), bind(&pt_t::first,_1), bind(&pt_t::first,_2)), 
     bind(std::plus<T>(), bind(&pt_t::second,_1), bind(&pt_t::second,_2)) 
    )); 
} 
관련 문제