27

randomコンパイル時にC++11 のライブラリを使用してランダムな値を事前計算しようとしています。私は主に例に従っています。ここで何が間違っていますか?

using namespace std;
#include <iostream>
#include <vector>
#include <random>

vector<double> rands;
typedef std::mt19937_64 RNG;
uint64_t seed_val;
RNG rng; 

void initialize() {
     rng.seed(seed_val);
}

constexpr vector<double> generate_random( )                 //size_t numbers)
{   
    int numbers = 1000;
    std::uniform_real_distribution<double> zero_one(0.0, 1.0);
        for (unsigned int i = 0; i < numbers; i++) { 
             double rand_num = zero_one(rng);
             rands.push_back( rand_num );
    }
    return rands;
}

int main()
{
    cout << "TMP rands";
    for_each( rands.begin(), rands.end(), [] (double value)
    {
        cout<<value<<endl;
    });
}

hereから恥知らずに盗まれたコンパイル時の乱数ジェネレーターの例を次に示しますが、これを調べる人にとっては役立つかもしれないと考えました。

template<u32 S, u32 A = 16807UL, u32 C = 0UL, u32 M = (1UL<<31)-1>
struct LinearGenerator {
    static const u32 state = ((u64)S * A + C) % M;
    static const u32 value = state;
    typedef LinearGenerator<state> next;
    struct Split { // Leapfrog
        typedef LinearGenerator< state, A*A, 0, M> Gen1;
        typedef LinearGenerator<next::state, A*A, 0, M> Gen2;
    };
};
4

7 に答える 7

27

constexprコンパイル時に評価できるのは、関数と定数式だけです。それは と を除外<chrono><random>ます。

できることは、プリプロセッサ マクロにアクセスして、1 行の関数__TIME__で構成される独自の PRNG を定義することです。constexpr

于 2012-07-16T05:02:11.717 に答える
8

このトピックに関する研究論文があります:トリックのコード スニペットを 含むC++ テンプレート メタプログラムの乱数ジェネレーター。また、直交する選択肢として、さまざまな乱数エンジンと分布をサポートすることについても説明しています。__TIME__

于 2014-04-14T10:21:51.623 に答える
4

外部ソースから引っ張ってみます。非常に単純な例は、コンパイル コマンドでマクロ変数を定義してプログラムをコンパイルすることです。$RANDOMこれは、ランダムな 16 ビット数を自動的に返す unix/linux システムの特別な組み込み変数です。

g++ -D__RANDOM__=$RANDOM yourprog.cpp -o yourprog

//yourprog.cpp
#include <iostream>
int main() {
  std::cout << "Random variable " << __RANDOM__ << std::endl;
  return 0;
}

独自のスクリプトまたは実行可能ファイルを記述して、マクロ変数に割り当てることもできます。

//DevRandomGenerator.cpp
#include <iostream>
#include <fstream>

class DevRandom {
private:
    std::ifstream stream;
public:

    DevRandom() {
        stream.open("/dev/urandom",std::ios::in|std::ios::binary);
    }

    unsigned int unsignedInt() {
        unsigned int u = 0;
        stream.read((char*)&u, sizeof(unsigned int));
        return u;
    }
};

int main() {
  DevRandom rand;
  std::cout << rand.unsignedInt() << std::endl;
  return 0;
}

次に、次のようにコンパイルします。

g++ DevRandomGenerator.cpp -o DevRandomGenerator
g++ -D__RANDOM__="$(./DevRandomGenerator)" yourprog.cpp -o yourprog

より良い乱数発生器は、オーディオとビジュアルの入力を使用するプログラムを作成することです。

于 2015-12-06T03:43:07.313 に答える
3

system_clock::now()コンパイル時に認識できないだけでなく、関数はブール値を返すとラベル付けされていますが、return ステートメントはどこにもありません。

于 2012-07-16T05:04:06.553 に答える
1

エラーメッセージに従って:

cpp11tmprands.cpp:22:15: エラー: 'rands' はこのスコープで宣言されていませんでした

のスコープで変数randsが宣言されていませんmain。ローカル変数ではなくグローバル変数にするgenerate_randomと、そのエラーはなくなります。

于 2012-07-16T05:10:40.137 に答える