fork(2) download
  1. #include <cassert>
  2. #include <cstdlib>
  3.  
  4. #include <array>
  5. #include <iostream>
  6. #include <numeric>
  7. #include <utility>
  8.  
  9. // Wraps a std::array of TKey/TValue pairs and provides a method
  10. // to randomly select a TKey with TValue bias.
  11. template< typename TKey, typename TValue, std::size_t TSize >
  12. class weights final
  13. {
  14. public:
  15. using pair = const std::pair< const TKey, const TValue >;
  16. using array = const std::array< pair, TSize >;
  17.  
  18. weights( array values )
  19. : values_{ values }
  20. , sum_{ std::accumulate(values_.begin(), values_.end(), 0, [](TValue total, const pair& p){ return total + p.second; }) }
  21. {}
  22.  
  23. // Implements this algorithm
  24. // http://stackoverflow.com/a/1761646/331024
  25. const TKey get() const
  26. {
  27. // The real code uses c++11 <random> features,
  28. // which I've removed for brevity.
  29. auto weight_rand = static_cast< TValue >( std::rand() % sum_ );
  30.  
  31. for ( std::size_t i = 0; i < TSize; ++i )
  32. {
  33. if (weight_rand < values_[i].second)
  34. {
  35. return values_[i].first;
  36. }
  37. weight_rand -= values_[i].second;
  38. }
  39. assert(false);
  40. }
  41.  
  42. private:
  43. array values_;
  44. const TValue sum_;
  45. };
  46.  
  47. enum class direction
  48. {
  49. NORTH,
  50. SOUTH,
  51. EAST,
  52. WEST
  53. };
  54.  
  55. // For convenience create a type to map the above
  56. // four-value enumeration to integer weights.
  57. using w4i = weights< direction, int, 4 >;
  58.  
  59. // Map the directions with a weight.
  60. static const w4i direction_weights = w4i::array{
  61. {
  62. w4i::pair{ direction::NORTH, 2 },
  63. w4i::pair{ direction::EAST, 1 },
  64. w4i::pair{ direction::SOUTH, 3 },
  65. w4i::pair{ direction::WEST, 1 }
  66. }
  67. };
  68.  
  69. int main()
  70. {
  71. std::cout << (int)direction_weights.get() << std::endl;
  72.  
  73. return 0;
  74. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In instantiation of ‘weights<TKey, TValue, TSize>::weights(array) [with TKey = direction; TValue = int; unsigned int TSize = 4u; weights<TKey, TValue, TSize>::array = const std::array<const std::pair<const direction, const int>, 4u>]’:
prog.cpp:67:5:   required from here
prog.cpp:20:137: error: could not convert ‘values’ from ‘weights<direction, int, 4u>::array {aka const std::array<const std::pair<const direction, const int>, 4u>}’ to ‘const std::pair<const direction, const int>’
                 , sum_{ std::accumulate(values_.begin(), values_.end(), 0, [](TValue total, const pair& p){ return total + p.second; }) }
                                                                                                                                         ^
stdout
Standard output is empty