The copy constructor for std::random_device
is deleted, and I have no idea why.
The only note I found from the docs is:
2) The copy constructor is deleted:
std::random_device
is not copyable.
There doesn't seem to be a clear reason for why it is deleted. What is the reason behind this?
Deleted Copy Constructor is used if you are Avoiding implicit generation of the copy constructor. In example, copy constructor can be defined with attributes as delete; This is a full example with a Deleted Copy Constructor, here we put reminder where compile error and avoids to generate a new class by using copy constructor,
- The Old New Thing Why does std::is_copy_constructible report that a vector of move-only objects is copy constructible? The std::is_copy_constructible traits class reports whether a type is copy-constructible. But it sometimes reports that a type is copy-constructible even though it isn’t.
The copy constructor doesn’t compile if you have a vector of move-only objects, but std::is_copy_constructible doesn’t try to compile the copy constructor. It just checks whether the copy constructor exists.
The std::vector and other collections claim to be copyable, but whethey they actually are copyable depends on what you put into them. We’ll investigate one of the consequences of this “Trust what it says on the tin” behavior next time.
The reason why std::random_device
is not copyable is that if it were, the copied instance may return exactly the same numbers as the original (this is implementation defined though)!
This is because (docs):
std::random_device
may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case eachstd::random_device
object may generate the same number sequence.
Some implementations will thus implement a PRNG. PRNGs are generally implemented with a seed value (and some other state), from which the "random" numbers are generated. By copying std::random_device
, this will copy the seed value, along any other internal state that the generator uses to generate random numbers (which is implementation defined).
You would have 2 random devices, which are deterministic because they generate the same number sequence:
std::random_device device1;
std::random_device device2 = device1; //For demonstration purposes only
std::uniform_int_distribution dis{ 0, 10 };
int randomNumber1 = dis(device1);
int randomNumber2 = dis(device2);
//Note that "randomNumber1 == randomNumber2"! They use exactly the same random number
//generator with the same seed value, etc. -> Same numbers are generated!
The implementation might always use the same seed values for every std::random_device
, which would mean that the same number sequence is generated every time for different random devices. Or it might use some non-deterministic source (taken from above):
In this case each
std::random_device
object may generate the same number sequence.
[...] if a non-deterministic source (e.g a hardware device) [...]
In those cases it doesn't matter that the random device is copyable (one would not think that the copy is in fact a copy), but it does matter where the implementation generates different values for different random devices using a PRNG.
Implementing the copy constructor (and the copy assignment operator) would break that assumption for the implementations that use a PRNG, and so it is deleted, to maintain the "randomness" of the numbers generated for every implementation (as long as the implementation allows it).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With