C++  convenience functions
To answer your questions:


Sure looks like it.
No, see next point.
No, it is not safe. std::mersenne_twister_engine::operator() reads and increments its internal state. AFAIK, this makes it not thread safe at all.


So, here are a few suggestions:


An extra semicolon hid itself in your code:

std::cout &lt;&lt; result.get() &lt;&lt; std::endl;;
                                       ^

Don't use std::endl. It implicitly uses std::flush to flush the stream. This is not very cheap, so it is better for performance if you just output '\n'.

If you do want to flush the stream, it would be better to state your intent and use std::flush, but this depends on you.
Mark functions that do not throw noexcept. That way, you state your intent that the functions will not throw, and it helps the compiler optimize a bit.
Currently, your shuffle takes a container. While that is desirable in most cases, sometimes, you just need to shuffle a subrange of a container. It's for exactly this reason that all the standard algorithms take an iterator pair instead of a container.
If you try to include Random.h more than once, you will get symbol collision for the variable generator. The same thing happens for functions. Here's what you can do:


Use C++17, and mark the variable inline, which behaves exactly like in functions:

thread_local inline std::mt19937_64 generator(std::random_device{}());

Mark the variable extern, and put its definition in Random.cpp.

You don't need return 0; at the end of main(). The compiler implicitly adds it for you.
I like to use types as parameter that try to match the preconditions of a function. For example, I would use unsigned integers everywhere where you use signed integers, because I do not see the point in calling let's say random_walk with a negative number_of_steps.
You can shorten the definitions in Random.cpp by removing Random:: if you wrap them around namespace Random, like in the declarations.