teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

更に追記

2016/12/23 05:29

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -84,3 +84,58 @@
84
84
  ```
85
85
 
86
86
  tTypeが整数(integral)の時後者のRandomクラス、それ以外の時前者のRandomクラスが実体化されます。
87
+
88
+ ---
89
+ 【michiru_cppさんのアイデアを貰って修正】
90
+
91
+ ```C++
92
+ # include <iostream>
93
+ # include <random>
94
+ # include <type_traits>
95
+ # include <ctime>
96
+
97
+ template<typename tType>
98
+ class Random
99
+ {
100
+ std::default_random_engine mEngine;
101
+ typename
102
+ std::conditional
103
+ <
104
+ std::is_integral<tType>::value,
105
+ std::uniform_int_distribution<tType>,
106
+ std::uniform_real_distribution<tType>
107
+ >::type mDistribution;
108
+ public:
109
+ Random(tType iMin, tType iMax) :
110
+ mEngine(time(nullptr)),
111
+ mDistribution(iMin, iMax)
112
+ { }
113
+
114
+ tType operator()()
115
+ {
116
+ return mDistribution(mEngine);
117
+ }
118
+ };
119
+
120
+ int main()
121
+ {
122
+ Random<int> aRandomInt(0, 4);
123
+ for(int i=0; i < 10; ++i)
124
+ {
125
+ std::cout << aRandomInt() << '\n';
126
+ }
127
+
128
+ Random<double> aRandomDouble(0, 4);
129
+ for(int i=0; i < 10; ++i)
130
+ {
131
+ std::cout << aRandomDouble() << '\n';
132
+ }
133
+
134
+ return 0;
135
+ }
136
+ ```
137
+
138
+ よし、同じことを2回書かずにできました。
139
+ なるほどstd::conditional<>強力です。
140
+
141
+ BeatStarさん。質問の主旨から外してしまってすいません。

2

追記

2016/12/23 05:29

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -17,4 +17,70 @@
17
17
 
18
18
  後、型だけが異なるものを作る時はテンプレートを活用するとよいです。
19
19
  スマートに書くには意外にC++11の機能を使いまくることになりそうですが。
20
- 後でサンプルを書いてみるかも知れません。(期待はしないで下さい。)
20
+ 後でサンプルを書いてみるかも知れません。(期待はしないで下さい。)
21
+
22
+ ---
23
+ 【追記】
24
+ サンプル作ってみました。
25
+ でもすいません。「型だけが異なるものを作る時はテンプレートを活用するとよいです」の効果が見える姿にできませんでした。
26
+ uniform_real_distribution<>とuniform_int_distribution<>を分岐させるために結局2つほぼ同じものを定義すると言うおまぬけです。コンパイル時処理になるのでそこそこ軽くはなっている筈ですが。
27
+
28
+ ```C++
29
+ # include <iostream>
30
+ # include <random>
31
+ # include <type_traits>
32
+ # include <ctime>
33
+
34
+ template<typename tType, class tEnable=void>
35
+ class Random
36
+ {
37
+ std::default_random_engine mEngine;
38
+ std::uniform_real_distribution<tType> mDistribution;
39
+ public:
40
+ Random(tType iMin, tType iMax) :
41
+ mEngine(time(nullptr)),
42
+ mDistribution(iMin, iMax)
43
+ { }
44
+
45
+ tType operator()()
46
+ {
47
+ return mDistribution(mEngine);
48
+ }
49
+ };
50
+
51
+ template<typename tType>
52
+ class Random<tType, typename std::enable_if<std::is_integral<tType>::value>::type>
53
+ {
54
+ std::default_random_engine mEngine;
55
+ std::uniform_int_distribution<tType> mDistribution;
56
+ public:
57
+ Random(tType iMin, tType iMax) :
58
+ mEngine(time(nullptr)),
59
+ mDistribution(iMin, iMax)
60
+ { }
61
+
62
+ tType operator()()
63
+ {
64
+ return mDistribution(mEngine);
65
+ }
66
+ };
67
+
68
+ int main()
69
+ {
70
+ Random<int> aRandomInt(0, 4);
71
+ for(int i=0; i < 10; ++i)
72
+ {
73
+ std::cout << aRandomInt() << '\n';
74
+ }
75
+
76
+ Random<double> aRandomDouble(0, 4);
77
+ for(int i=0; i < 10; ++i)
78
+ {
79
+ std::cout << aRandomDouble() << '\n';
80
+ }
81
+
82
+ return 0;
83
+ }
84
+ ```
85
+
86
+ tTypeが整数(integral)の時後者のRandomクラス、それ以外の時前者のRandomクラスが実体化されます。

1

補足

2016/12/23 03:43

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -3,6 +3,9 @@
3
3
  原因は、MinGWの実装が期待と異なることですね。
4
4
  「cpprefjp - C++日本語リファレンス」に記載されている「実装の制限によって予測不能な乱数生成器を定義できない場合、このクラスは擬似乱数生成器で定義される可能性がある。」にMinGWは残念ながら該当するようです。
5
5
 
6
+ [C++ MinGWを使用した場合にstd::random_deviceが毎回同じ値を出力する問題について](http://qiita.com/mekamikan/items/f9a15e4e96975380c1bf)
7
+ [Why do I get the same sequence for every run with std::random_device with mingw gcc4.8.1?](http://stackoverflow.com/questions/18880654/why-do-i-get-the-same-sequence-for-every-run-with-stdrandom-device-with-mingw)
8
+
6
9
  安易な対策は下記と思います。
7
10
 
8
11
  > default_random_engine engine( time(nullptr) );