From: Vladimir Grigoriev on 18 Jan 2010 06:48 Why is the RandomNumber Generator parameter passed by reference in the std::random_shuffle() while other algorithms take a function parameter by value? What is the reason? When a function parameter is passed by reference it can not be built on the fly. For example std::random_shuffle( first, last, UserRandomNumberGenerator() ); // is not compiled Vladimir Grigoriev
From: Igor Tandetnik on 18 Jan 2010 11:50 Vladimir Grigoriev wrote: > Why is the RandomNumber Generator parameter passed by reference in the > std::random_shuffle() while other algorithms take a function parameter by > value? Random number generators usually have state. Things like, say, predicates are typically stateless. > What is the reason? When a function parameter is passed by reference > it can not be built on the fly. Why would you want to? -- With best wishes, Igor Tandetnik With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
From: Vladimir Grigoriev on 18 Jan 2010 12:10 However a state can be kept inside a functional class. So I think your reason is not sufficient. Vladimir Grigoriev "Igor Tandetnik" <itandetnik(a)mvps.org> wrote in message news:%23pE395FmKHA.1824(a)TK2MSFTNGP04.phx.gbl... Vladimir Grigoriev wrote: > Why is the RandomNumber Generator parameter passed by reference in the > std::random_shuffle() while other algorithms take a function parameter by > value? Random number generators usually have state. Things like, say, predicates are typically stateless. > What is the reason? When a function parameter is passed by reference > it can not be built on the fly. Why would you want to? -- With best wishes, Igor Tandetnik With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
From: Tamas Demjen on 18 Jan 2010 16:52 Vladimir Grigoriev wrote: > However a state can be kept inside a functional class. So I think your > reason is not sufficient. Because you usually don't want to reset the seed of the random number generator. Instead, you want to continue where your previous random number was left off. Imagine that you are writing a card game, and random_shuffle's last parameter is passed by value in the following code: UserRandomNumberGenerator rand(initial_seed); while(!quit) { int A[] = {1, 2, 3, 4, 5, 6, 7, 8}; random_shuffle(A, A + N, rand); PlayCardGame(A, A + N); } So if this is a solitaire game, the player would see the exact same order of cards in every single game. :-) However, since random_shuffle's last argument is a reference, this problem does not exist. Tom
From: Stephan T. Lavavej [MSFT] on 18 Jan 2010 17:57 There's a little more to the story than this. First, I want to correct an earlier reply: [Igor Tandetnik] > Things like, say, predicates are typically stateless. This is incorrect. Some predicates are stateless, like is_even. Other predicates are stateful, like bind(less<int>(), _1, 1729). Predicates (and comparators) almost never *modify* their state as they are invoked, because they must return consistent answers, but constructing a stateful predicate and giving it to an STL algorithm is a common and useful thing to do. Tamas explained most of the story below - PRNGs modify their state, and typically you want to keep using the modified state instead of discarding it. However, the STL has an algorithm that takes a functor by value, invokes it on every element of a sequence, and *returns* that functor, allowing the functor to modify its state along the way so that it can be inspected later. This algorithm is called for_each(). So why doesn't random_shuffle() behave like for_each()? I can think of a couple of reasons. First, taking the PRNG by reference makes it difficult to drop the modified state on the floor. (This was probably the most important reason during C++98's standardization.) Second, PRNGs often maintain a lot of state, unlike other functors which are expected to be lightweight (the STL usually passes functors by value). For example (an anachronistic example), mersenne_twister maintains a lot of state. Copying that around, in the absence of move semantics, is undesirable. STL "Tamas Demjen" <tdemjen(a)yahoo.com> wrote in message news:%23fEVQiImKHA.4872(a)TK2MSFTNGP05.phx.gbl... > Vladimir Grigoriev wrote: >> However a state can be kept inside a functional class. So I think your >> reason is not sufficient. > > Because you usually don't want to reset the seed of the random number > generator. Instead, you want to continue where your previous random > number was left off. > > Imagine that you are writing a card game, and random_shuffle's last > parameter is passed by value in the following code: > > UserRandomNumberGenerator rand(initial_seed); > while(!quit) > { > int A[] = {1, 2, 3, 4, 5, 6, 7, 8}; > random_shuffle(A, A + N, rand); > PlayCardGame(A, A + N); > } > > So if this is a solitaire game, the player would see the exact same > order of cards in every single game. :-) > > However, since random_shuffle's last argument is a reference, this > problem does not exist. > > Tom
|
Next
|
Last
Pages: 1 2 Prev: SetMapMode and MouseMove messages Next: SetMapMode and MouseMove messages |