0

I want to create a function which returns the index of vector randomly according to the value of element as probability:

float getRandomIndex(const vector<float>& v){
    random_device r;
    mt19937 m(r());
    return discrete_distribution<>(v.begin(),v.end())(m);
}

int main(){
    for(int i=0;i<10;i++){
        vector<float> a{0.9,0.1};
        cout << getRandomIndex(a) << endl;
    }
    return 0;
}

now I want to reduce line numbers, so try to rewrite the function as:

float getRandomIndex(const vector<float>& v){
    mt19937 m(random_device()());
    return discrete_distribution<>(v.begin(),v.end())(m);
}

but failed to compile:

error: function cannot return function type 'std::__1::random_device ()'
mt19937 m(random_device()());
                       ^
warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
mt19937 m(random_device()());
         ^~~~~~~~~~~~~~~~~~~
note: add a pair of parentheses to declare a variable
mt19937 m(random_device()());
          ^
          (

1 warning and 1 error generated.

but I try

random_device r;
cout << r() << endl;

and

cout << random_device()() << endl;

they seems have the same function, why I cannot replace the variable r to a immediately created random_device in mt19937?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
ggrr
  • 7,737
  • 5
  • 31
  • 53
  • If it helps in order to picture it, you have a function called `m` that takes, as a parameter, a function return a function that takes nothing and returns a `random_device`. `m` returns an `mt19937`. – chris Dec 04 '15 at 05:49
  • 1
    `add a pair of parentheses to declare a variable` Did you not try following that advice? I mean, your compiler went through a lot of effort to point out exactly where you might need those parens. – Nicol Bolas Dec 04 '15 at 05:56
  • And it has nothing to do with `mt19937` or `random_device`. – juanchopanza Dec 04 '15 at 08:06

1 Answers1

5

The most vexing parse strikes again! In this case, it looks like the random_device()() part gets parsed as a function returning a function returning a random_device. In cases like this, the code could either be creating a temporary variable, or declaring a function. The compiler is forced to assume it is a function declaration.

You can fix it with braces or extra parenthesis.

m(random_device{}()) //uniform initialization syntax, will work
m((random_device()())) //extra parenthesis, also will work
Weak to Enuma Elish
  • 4,622
  • 3
  • 24
  • 36