Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You're getting close with your edits. You need to restrict your "integral" version to integral types. That will get rid of the ambiguity:</p> <pre><code>template&lt;typename T&gt; typename std::enable_if &lt; std::is_integral&lt;T&gt;::value, T &gt;::type randomPrimitive() </code></pre> <p>But if you run it now with something like this:</p> <pre><code>#include &lt;iostream&gt; int main() { for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;float&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;double&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; (int)randomPrimitive&lt;signed char&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;unsigned&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;bool&gt;() &lt;&lt; '\n'; } </code></pre> <p>You'll get something like:</p> <pre><code>0.814724 0.814724 0.814724 0.814724 0.814724 0.814724 0.814724 0.814724 0.814724 0.814724 0.135477 0.135477 0.135477 0.135477 0.135477 0.135477 0.135477 0.135477 0.135477 0.135477 92 92 92 92 92 92 92 92 92 92 3499211612 3499211612 3499211612 3499211612 3499211612 3499211612 3499211612 3499211612 3499211612 3499211612 1 1 1 1 1 1 1 1 1 1 </code></pre> <p>Getting there, but not exactly random. The problem is that you are constructing a new engine every time you use it. What you want is to create a URNG once, and then keep getting random bits out of it:</p> <pre><code>std::mt19937&amp; get_eng() { static std::mt19937 eng; return eng; } </code></pre> <p>And you should really only create your distributions once too. Most of them are stateless, but not all of them. Best just to assume all of them carry state, and you don't want to throw that state away.</p> <pre><code>static std::uniform_real_distribution&lt;T&gt; dst; </code></pre> <p>This will greatly improve things, but you're not there yet:</p> <pre><code>0.814724 0.135477 0.905792 0.835009 0.126987 0.968868 0.913376 0.221034 0.632359 0.308167 0.547221 0.188382 0.992881 0.996461 0.967695 0.725839 0.98111 0.109862 0.798106 0.297029 92 13 49 122 46 7 105 45 43 8 2816384844 3427077306 153380495 1551745920 3646982597 910208076 4011470445 2926416934 2915145307 1712568902 0 1 1 1 1 0 1 0 1 0 </code></pre> <p>I note that all 10 of the values from <code>signed char</code> are positive. That doesn't look right. It turns out that <code>std::uniform_int_distribution</code> has a constructor that looks like this:</p> <pre><code>explicit uniform_int_distribution(IntType a = 0, IntType b = numeric_limits&lt;IntType&gt;::max()); </code></pre> <p>I'm guessing that's not what you want, so:</p> <pre><code>static std::uniform_int_distribution&lt;T&gt; dst(std::numeric_limits&lt;T&gt;::min(), std::numeric_limits&lt;T&gt;::max()); </code></pre> <p>And finally, if you want a random <code>bool</code>, go with the <code>std::bernoulli_distribution</code>.</p> <p>Putting this all together:</p> <pre><code>#include &lt;random&gt; std::mt19937&amp; get_eng() { static std::mt19937 eng; return eng; } template&lt;typename T&gt; typename std::enable_if &lt; std::is_integral&lt;T&gt;::value, T &gt;::type randomPrimitive() { static std::uniform_int_distribution&lt;T&gt; dst(std::numeric_limits&lt;T&gt;::min(), std::numeric_limits&lt;T&gt;::max()); return dst(get_eng()); } template&lt;&gt; bool randomPrimitive&lt;bool&gt;() { static std::bernoulli_distribution dst; return dst(get_eng()); } template&lt;typename T&gt; typename std::enable_if &lt; std::is_floating_point&lt;T&gt;::value, T &gt;::type randomPrimitive() { static std::uniform_real_distribution&lt;T&gt; dst; return dst(get_eng()); } #include &lt;iostream&gt; int main() { for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;float&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;double&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; (int)randomPrimitive&lt;signed char&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;unsigned&gt;() &lt;&lt; '\n'; for (int i = 0; i &lt; 10; ++i) std::cout &lt;&lt; randomPrimitive&lt;bool&gt;() &lt;&lt; '\n'; } </code></pre> <p>Which for me outputs:</p> <pre><code>0.814724 0.135477 0.905792 0.835009 0.126987 0.968868 0.913376 0.221034 0.632359 0.308167 0.547221 0.188382 0.992881 0.996461 0.967695 0.725839 0.98111 0.109862 0.798106 0.297029 92 13 -79 -6 46 -121 -23 45 43 8 2816384844 3427077306 153380495 1551745920 3646982597 910208076 4011470445 2926416934 2915145307 1712568902 0 1 1 1 1 0 1 0 1 0 </code></pre> <p>And if this still isn't outputting what you intended, hopefully you've got enough direction to take it from here.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload