Simple random generator Based on this question, I have made a simple program to print a sequence of random numbers. The program seems to run fine, but I would like to know if my implementation is correct and how I can improve it.

#include &lt;random&gt;
#include &lt;array&gt;
#include &lt;algorithm&gt;
#include &lt;functional&gt;
#include &lt;iostream&gt;

template&lt;class T = std::mt19937, std::size_t N = T::state_size&gt;
auto randomEngine() -&gt; typename std::enable_if_t&lt;!!N, T&gt;
{
    std::array&lt;typename T::result_type, N&gt; seed_data;
    thread_local static std::random_device source;
    std::generate(std::begin(seed_data), std::end(seed_data), std::ref(source));
    std::seed_seq seeds(std::begin(seed_data), std::end(seed_data));
    thread_local static T seeded_engine(seeds);
    return seeded_engine;
}

template&lt;typename T&gt;
T random(T min, T max)
{
    static_assert(std::is_integral&lt;T&gt;::value || std::is_floating_point&lt;T&gt;::value, "!");

    using UniformInt = std::uniform_int_distribution&lt;T&gt;;
    using UniformReal = std::uniform_real_distribution&lt;T&gt;;
    using DistType = std::conditional_t&lt;std::is_integral&lt;T&gt;::value, UniformInt, UniformReal&gt;;

    static auto RandomEngine = randomEngine();

    DistType uniformDistribution(min, max);

    return uniformDistribution(RandomEngine);
}

int main()
{
    for (auto i = 0u; i &lt; 16; ++i) 
        std::cout &lt;&lt; random(0u, 15u) &lt;&lt; ' ';
}
Extra typenames

Every place you use typename, it's unnecessary. std::enable_if_t will take care of that for you.

thread_local

First of all, thread_local implies static, so writing both is redundant. Secondly, if you're making it thread_local, that's effectively like making a thread-specific singlelton - so you should return a reference to it, not a copy:

template&lt;class T = std::mt19937, std::size_t N = T::state_size&gt;
auto randomEngine() -&gt; std::enable_if_t&lt;!!N, T&amp;&gt;


And take it by reference:

static auto&amp; RandomEngine = randomEngine();


random()

I'm not sure it's a good idea to create the distribution every time. The distribution object itself can keep state, so I think it'd be a better idea to take it in instead:

template &lt;class Dist&gt;
typename Dist::result_type random(Dist&amp; dist)
{
    static auto&amp; RandomEngine = randomEngine();
    return dist(RandomEngine);
}


And alter dist&lt;T&gt; to take arguments so that you could do:

auto d = dist&lt;unsigned&gt;(0, 15);
for (auto i = 0u; i &lt; 16; ++i) 
    std::cout &lt;&lt; random(d) &lt;&lt; ' ';