4

私はVC 2010を使用しており、各クラスインスタンスのコンストラクターにランダムな定義を配置し、必要に応じてそこから呼び出すことにより、特定の関数のオーバーヘッドと重複コードを低く抑えようとしています。私が今持っているものは、単純化すると次のとおりです。

#include <random>
#include <Windows.h>
mt19937 eng(GetTickCount());

class Cycles {
    int line;
    normal_distribution<> rand_norm;
    variate_generator<mt19937&,normal_distribution<>> r_norm;
public:
    Cycles() 
    : rand_norm(0.85,0.05),
      r_norm(eng,rand_norm) { 
        line=0; 
    }
}

残念ながら、それは機能せず、次のエラーが発生します。

\vc\include\random(513): エラー C2248: 'std::tr1::_Ewrap<_Engine,_Tgt_type>::operator =': クラスで宣言されたプライベート メンバーにアクセスできません 'std::tr1::_Ewrap<_Engine, _Tgt_type>'

\vc\include\random(446) : 'std::tr1::_Ewrap<_Engine,_Tgt_type>::operator =' の宣言を参照してください

この診断は、コンパイラによって生成された関数 'std::tr1::variate_generator<_Engine,_Distrib> &std::tr1::variate_generator<_Engine,_Distrib>::operator =(const std::tr1::variate_generator<_Engine,_Distrib) で発生しました。 > &)'

コンストラクターを開く前にこれらを初期化する必要があることは理解しています。そうしないと、デフォルトのコンストラクターがないためにエラーが発生しますが、なぜこれが失敗するのかわかりません。私の C++ fu はかなり錆びています。

私が見たすべての例は、ディストリビューターとジェネレーターがそれを呼び出す関数でグローバルまたはローカルに初期化されていることを示しています。これは、タイトなループで呼び出される r_norm を使用するいくつかのメンバー関数があるため、ばかげているように思えます。においテストにひどく失敗します。私が欠けているものを誰も知りませんか?

4

3 に答える 3

6

bind()の代わりに c++0x で使用されますvariate_generator<>

#include <functional> // bind
#include <iostream>
#include <vector>
#include <random>

namespace {
  std::random_device generate_seed;
  std::mt19937 eng(generate_seed());    
  class Cycles {
    int line;
    std::normal_distribution<> rand_norm;
    std::function<double()> r_norm;
  public:
    Cycles(): line(0), rand_norm(0.85, 0.05), r_norm(std::bind(rand_norm, eng))
    {
      // print distribution
      std::vector<size_t> freq(200);
      for (int i = 0; i < 900; ++i) ++freq.at(std::round(r_norm()*100));

      size_t line = 0, max_line = freq.size()-1;
      for ( ; not freq[line] and line <= max_line;  ++line);
      for ( ; not freq[max_line] and max_line >= line; --max_line);
      for ( ; line <= max_line; ++line) {
        std::cout << line << '\t';
        for (size_t j = 0; j < freq[line]; ++j) std::cout << '*';
        std::cout << std::endl;
      }
    }
  };
}    
int main() {
  Cycles c;
}

プロットはC++0xFAQに触発されています。

出力

72 **
73 ***
74 ******
75 ********
76 *****************
77 ********************
78 *******************************
79 ************************************************
80 *************************************************
81 **********************************************************
82 ************************************************************
83 ***********************************************************
84 ************************************************************************
85 ********************************************************************************
86 *********************************************************************
87 ************************************************************
88 ****************************************************
89 *************************************
90 **********************************
91 **************************************
92 *************************
93 ******************
94 ********************
95 ************
96 ****
97 **********
98 ***
99 **
100 **
101 *
于 2010-12-16T17:41:20.183 に答える
3

手元にMSVCはありませんが、gccを使用すると、これを置き換えるとコンパイルされます

variate_generator<mt19937&,normal_distribution<>> r_norm;

variate_generator<mt19937, normal_distribution<> > r_norm;

(の欠如に注意してください&

ちなみに、MSVCでどのように実装されているかはわかりませんが、std::random_deviceおそらくランダム性のより良いソースです。GetTickCount()

于 2010-10-16T05:13:53.723 に答える
-1
mt19937 eng(GetTickCount());

非静的な式でグローバル変数を初期化することはできません。

于 2010-10-16T04:25:48.843 に答える