error: call of overloaded ‘discrete_distribution(<brace-enclosed initializer list>)’ is ambiguous

Hello People,

I am trying to write a function that produces random indexes on the interval of indexes of a vector v (let's say [0 m)).
The probability of each individual index i is defined by the weight of the value which corresponds to the ith index in v with respect to the sum of all m weights (values), in v.
This function uses std::discrete_distribution.

Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::vector<int>        getRandomWeightedIndexes( const std::vector<double>& v,
                                                  const std::size_t n )
{
        std::vector<int>        v1;
        std::random_device rd;
        std::mt19937 gen(rd());
        std::discrete_distribution<> d({v.begin(),v.end()});
        for(std::size_t i = 0; i < n; i++) {
                auto    index = d(gen);
                while(std::find(v1.begin(), v1.end(), index) != v1.end())
                        index = d(gen);

                v1.push_back(index);
        }
        v1.shrink_to_fit();

        return  v1;
} // end function getRandomWeightedIndexes 


When I compile this code, I receive the following error:

1
2
error: call of overloaded ‘discrete_distribution(<brace-enclosed initializer list>)’ is ambiguous
std::discrete_distribution<> d({v.begin(),v.end()});


The command for compilation is:

 
g++-5 -c -fopenmp -Wall -std=c++14


I have tested it with c++17 too, but same error.

The version of my compiler is:
 
g++-5 5.4.1-2ubuntu1~14.04 amd64 GNU C++ compiler


When I test the next code in coliru,
everything works just right when I
compile and run with the following command
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

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
#include <iostream>
#include <random>
#include <vector>
#include <algorithm>

 
int main()
{
    std::vector<std::size_t>    v = {1,2,3,4,5,6,700,80,900,100},v1;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::discrete_distribution<> d({v.begin(),v.end()});
    for(int n = 0; n < 5; n++) {
        auto    index = d(gen);
        while(std::find(v1.begin(), v1.end(), index) != v1.end()) {
            index = d(gen);
        }
        v1.push_back(index);
    }

    std::cout << "\nv:\n";
    for(const auto& s : v)
        std::cout << s << " ";
    std::cout << "\n";
    
    std::cout << "\nv1:\n";
    for(const auto& s : v1)
        std::cout << s << " ";
    std::cout << "\n";
}


Can anybody out there figure out what is happening?

Thanks

Dario
Last edited on
I don't think you should use those extra pair of braces when constructing the object.

 
std::discrete_distribution<> d(v.begin(), v.end());
Last edited on
you don't need the initial holding std::vector v but can pass the initializer list of values (currently held in v) to the std::discrete_distribution ctor directly as shown in the cppref link here and your code syntax sort of mirrors it but then perhaps got conflated:

http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution
Thanks Peter87!

Dear gunnerfunner, I do need v, because I want to use discrete_distribution in a function and the initializer is received as an argument. The second program is just a test.

Thanks!
... I do need v...
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
#include <iostream>
#include <random>
#include <vector>
#include <algorithm>


int main()
{
    std::vector<std::size_t>   /* v = {1,2,3,4,5,6,700,80,900,100},*/v1;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::discrete_distribution<> d({1,2,3,4,5,6,700,80,900,100});
    for(int n = 0; n < 5; n++) {
        auto    index = d(gen);
        while(std::find(v1.begin(), v1.end(), index) != v1.end()) {
            index = d(gen);
        }
        v1.push_back(index);
    }

 /*   std::cout << "\nv:\n";
    for(const auto& s : v)
        std::cout << s << " ";
    std::cout << "\n";*/

    std::cout << "v1:\n";
    for(const auto& s : v1)
        std::cout << s << " ";
    std::cout << "\n";
}
Topic archived. No new replies allowed.