    #include <cassert>
    #include <cstdlib>
    
    #include <array>
    #include <iostream>
    #include <numeric>
    #include <utility>

    // Wraps a std::array of TKey/TValue pairs and provides a method
    // to randomly select a TKey with TValue bias.
    template< typename TKey, typename TValue, std::size_t TSize >
    class weights final
    {
        public:
            using pair = const std::pair< const TKey, const TValue >;
            using array = const std::array< pair, TSize >;
    
            weights( array values )
                : values_{ values }
                , sum_{ std::accumulate(values_.begin(), values_.end(), 0, [](TValue total, const pair& p){ return total + p.second; }) }
            {}

            // Implements this algorithm
            // http://stackoverflow.com/a/1761646/331024
            const TKey get() const
            {
                // The real code uses c++11 <random> features,
                // which I've removed for brevity.
                auto weight_rand = static_cast< TValue >( std::rand() % sum_ );

                for ( std::size_t i = 0; i < TSize; ++i )
                {
                    if (weight_rand < values_[i].second)
                    {
                        return values_[i].first;
                    }
                    weight_rand -= values_[i].second;
                }
                assert(false);
            }

        private:
            array values_;
            const TValue sum_;
    };

    enum class direction
    {
        NORTH,
        SOUTH,
        EAST,
        WEST
    };

    // For convenience create a type to map the above
    // four-value enumeration to integer weights.
    using w4i = weights< direction, int, 4 >;

    // Map the directions with a weight.
    static const w4i direction_weights = w4i::array{
        {
            w4i::pair{ direction::NORTH, 2 },
            w4i::pair{ direction::EAST, 1 },
            w4i::pair{ direction::SOUTH, 3 },
            w4i::pair{ direction::WEST, 1 }
        }
    };

    int main()
    {
        std::cout << (int)direction_weights.get() << std::endl;    
    
        return 0;
    }