2013-03-06 28 views
2

我正在嘗試使用提升累加器來計算滾動平均值。當我聲明這樣的內聯變量:可以提升累加器作爲班員使用

#include <iostream> 
#include <boost/accumulators/accumulators.hpp> 
#include <boost/accumulators/statistics/stats.hpp> 
#include <boost/accumulators/statistics/rolling_mean.hpp> 

using namespace boost::accumulators; 

int main() 
{ 
    // Define rolling_mean accumulator 
    accumulator_set<double, stats<tag::rolling_mean > > acc(tag::rolling_window::window_size = 5); 
    // push in some data ... 
    acc(1.2); 
    acc(2.3); 
    acc(3.4); 
    acc(4.5); 

    // Display the results ... 
    std::cout << "Mean: " << rolling_mean(acc) << std::endl; 

    return 0; 
} 

它工作得很好。當我宣佈蓄電池作爲像這樣一類的成員:

#include <iostream> 
#include <boost/accumulators/accumulators.hpp> 
#include <boost/accumulators/statistics/stats.hpp> 
#include <boost/accumulators/statistics/rolling_mean.hpp> 

using namespace boost::accumulators; 

class DoMean { 
private: 
    accumulator_set<double, stats<tag::rolling_mean > > m_acc(tag::rolling_window::window_size = 5); 

public: 

    void addData(double val) { 
    this->m_acc(val); 
    } 

    double getMean(void) { 
    return rolling_mean(this->m_acc); 
    } 
}; 

int main() 
{ 
    // Define an accumulator set for calculating the mean and the 
    // 2nd moment ... 
    DoMean meaner; 
    meaner.addData(1.2); 
    meaner.addData(2.3); 
    meaner.addData(3.4); 
    meaner.addData(4.5); 

    // push in some data ... 

    // Display the results ... 
    std::cout << "Mean: " << meaner.getMean() << std::endl; 

    return 0; 
} 

它失敗,給編譯器錯誤:

accumulators::tag::rolling_window::window_size is not a type 
...blah blah, many type template errors etc. 

回答

8

正確的解決這個問題是這樣的:

#include <iostream> 
#include <boost/accumulators/accumulators.hpp> 
#include <boost/accumulators/statistics/stats.hpp> 
#include <boost/accumulators/statistics/rolling_mean.hpp> 

using namespace boost::accumulators; 

class DoMean { 
private: 
    accumulator_set<double, stats<tag::rolling_mean > > m_acc; 

public: 

    DoMean(void): m_acc(tag::rolling_window::window_size = 5) {} 

    void addData(double val) { 
    this->m_acc(val); 
    } 

    double getMean(void) { 
    return rolling_mean(this->m_acc); 
    } 
}; 

int main() 
{ 
    // Define an accumulator set for calculating the mean and the 
    // 2nd moment ... 
    DoMean meaner; 
    meaner.addData(1.2); 
    meaner.addData(2.3); 
    meaner.addData(3.4); 
    meaner.addData(4.5); 

    // push in some data ... 

    // Display the results ... 
    std::cout << "Mean: " << meaner.getMean() << std::endl; 

    return 0; 
} 

請注意,m_acc的初始化已經從它的聲明內聯移動到初始化列表中。這解決了所有編譯器錯誤。事實上,如果我們考慮這裏發生的事情,那麼在類中使用累加器的初始嘗試失敗的原因是因爲ISO C++禁止內聯成員的初始化。

我們可以用另一種簡單的類證明這一點:

#include <iostream> 

class TestInit { 
public: 
    int m_init = 10; 

}; 

int main() { 
    TestInit inits; 
    std::cout << "The value: " << inits.m_init << std::endl; 

} 

現在,編譯器爲我們提供了一個有用的信息:

/home/me/prog/cpp/acctest/testinit.cxx:5:16: error: ISO C++ forbids initialization of member m_init [-fpermissive] 
/home/me/prog/cpp/acctest/testinit.cxx:5:16: error: making m_init static [-fpermissive] 
/home/me/prog/cpp/acctest/testinit.cxx:5:16: error: ISO C++ forbids in-class initialization of non-const static member m_init 
+0

我認爲C++ 11允許這一點,我做的成員初始化中我的代碼。 – 2014-04-04 19:09:15