C++11 Random library usage in lambdas

Someone recently asked how to generate strings filled with random letters, so I suggested std::generate() and C++11's random library.

Later when I tried to write a solution myself, I realized that the program displays the same string every time it's run. (And also if recompiled without modifications.)

tl;dr: why isn't the output of this program random?
Using nuwen's MinGW 4.7.2 distribution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// http://cplusplus.com/forum/windows/86580/

#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <random>
#include <string>

int main()
{
	const std::size_t defaultStringLength = 10;

	std::default_random_engine prne;
	std::uniform_int_distribution<char> uid('A', 'z');
	auto randomCharacter = std::bind(uid, prne);
	std::string s(defaultStringLength, ' ');

	std::generate(s.begin(), s.end(), [&randomCharacter]() -> char {
		while (true)
		{
			const char c = randomCharacter();

			if (std::isalpha(c))
				return c;
		}
	});

	std::cout << s << std::endl;
}
Like always, you need to seed your RNG.
Embarrassing.

@ Peter87: thanks for the reply.
For variety, this could be done without a loop (but also without a lambda)

1
2
3
4
5
std::vector<double> bounds = {'A', 'Z'+1, 'a', 'z'+1};
std::vector<double> weights = {   1,  0,   1};
std::piecewise_constant_distribution<> d(bounds.begin(), bounds.end(), weights.begin());

std::generate(s.begin(), s.end(), bind(d, ref(prne)));


demo: http://ideone.com/4JgKjf
Last edited on
Thanks, Cubbi.

For anyone wondering what std::ref() does (since it doesn't appear in this site's Reference yet):
http://en.cppreference.com/w/cpp/utility/functional/ref
Topic archived. No new replies allowed.