質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Boost

Boost (ブースト)は、C++の先駆的な開発者のコミュニティ、 またそのコミュニティによって公開されているオープンソースライブラリのことを指します。

Q&A

解決済

2回答

2023閲覧

BoostのRandomをクラス化する方法

BeatStar

総合スコア4958

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Boost

Boost (ブースト)は、C++の先駆的な開発者のコミュニティ、 またそのコミュニティによって公開されているオープンソースライブラリのことを指します。

0グッド

0クリップ

投稿2016/08/15 00:38

C/C++ ( BetterC ) でやっています。
Cの標準関数 rand関数 はあまりよくないようなので、
Boostの Randamというものを使って乱数を発行したいと思っています。

ですが、そのままだと使いづらいので、自分が使いやすいようなクラスにしたいと思っています。

Boostのは、
Randomジェネレータを生成してrandで取得

らしいのですが、
これをクラスにする方法がわかりません。

私の考えでは、

通常のクラス ( テンプレートなし ) で、
コンストラクタで ジェネレータを生成し、
get系で取得する

という感じです。

実装例は

C++

1class CRand 2{ 3 public: 4 // コンストラクタ 5 CRand( double min, double max, int seed = time(NULL) ){ 6 // ここでジェネレータ ( どういう乱数か ) を生成 7 } 8 9 // デストラクタ 10 ~CRand(){} 11 12 // get系 13 double Get(){ 14 return rand(); 15 } 16 private: 17 // ここに生成したジェネレータ等のオブジェクトがある 18};

で、

C++

1int main(){ 2 3 // 0 から 100 までで、time(NULL)を seed として乱数を発行するオブジェクト 4 CRand* Random = new CRand( 0, 100 ); 5 6 for( int i = 0; i < 10; i++ ){ 7 cout << Random->Get() << endl; 8 } 9 10 delete Random; 11return 0; 12}

のように、
使うときは

インスタンス化のときに (最小値,最大値,シード値) を渡して
あとはひたすらfor文かwhile文で回しながら 取得...

みたいにしたいのです。

ですが、これを記述 ( もちろんBoost付属のサンプルソースを見て記述 ) して実行したところ、
乱数がうまく発行されないようです。
(発行されていても、常に同じ値。乱数とはいえない。)

同じブロック内 ( main関数内、自作関数内 等 ) ではちゃんと発行されます。

関数でもいいですが、
vectorまたはlistで取得するしかない ( または一個だけ ) ので、
クラスにして...

という感じがいいです。

C++のテンプレート ( テンプレートだけじゃないですが... ) ってかなりわかりづらいので、
どういじればいいのか...

[環境等]
コンパイラ : g++ ( MinGW )
言語 : C/C++ ( betterC )
知りたいこと: Boost の Randomをクラス化する方法 ( ただし、templateを使わない方法 )

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

boost.random じゃなく、標準C++ <random> 使って:

C++

1#include <random> 2#include <ctime> 3 4class CRand { 5public: 6 // コンストラクタ 7 CRand( double min, double max, int seed = time(NULL) ) 8 : generator_(seed), distribution_(min, max) {} 9 ~CRand(){} 10 11 // get系 12 double Get() { return distribution_(generator_); } 13private: 14 std::mt19937 generator_; 15 std::uniform_real_distribution<double> distribution_; 16}; 17 18#include <iostream> 19 20int main(){ 21 // 0 から 100 までで、time(NULL)を seed として乱数を発行するオブジェクト 22 CRand* Random = new CRand( 0, 100 ); 23 24 for( int i = 0; i < 10; i++ ){ 25 std::cout << Random->Get() << std::endl; 26 } 27 delete Random; 28 29}

投稿2016/08/15 01:15

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2016/08/15 06:48

これしきにクラス作るのもなー... mt19937 gen(time(nullptr)); uniform_real_distribution<double> dist(min, max); auto rand = [&]() { return dist(gen); } for ( ... ) { cout << rand() << endl; }
guest

0

こんにちは。

同じブロック内 ( main関数内、自作関数内 等 ) ではちゃんと発行されます。

ということはCRandクラスの作り方の問題ではなく、使い方の問題ではないでしょうか?
うまく動作しないケースの最小限のソースを提示して頂いた方がよいと思います。

知りたいこと: Boost の Randomをクラス化する方法 ( ただし、templateを使わない方法 )

Boost自体がテンプレートの塊ですので、Boostを使う際にテンプレートを使わないのは現実的ではないと思います。
Boostのソース読むのは非常に難易度が高いですが、Boostの浅い部分を使うだけならテンプレートというか、型システムの概要を理解しておけば十分ですので、ベターCerでも現実的と思いますよ。
std::vector<>を使うのにテンプレートを深く知っておく必要はないでしょう。それと同じです。

投稿2016/08/15 01:11

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問