-2

I have a map of actions to be taken upon certain choice,

struct option {
  int num;
  std::string txt;
  std::function<void(void)> action;
};
void funct_with_params(int &a, int &b)
{
    a = 3; b = 4;
}
int param1 = 1;
int param2 = 3;

I want to initialize vector of those in the new initializer list fashion:

const std::vector<option> choices
{ 
    {
        1,
        "sometext",
        std::bind(&funct_with_params, std::ref(param1), std::ref(param2))
    },
}

I can't get the initialization in the vector for function to work, is there a method of passing the std::bind to the vector in some way?

I was able to make the example work by using lambda expression instead of the bind, is there something I am missing? Or is it not the proper way of using std::bind?

I am using C++11 since I'm unable to move to a newer standard.

jotik
  • 17,044
  • 13
  • 58
  • 123
cerkiewny
  • 2,761
  • 18
  • 36
  • 3
    I [can't reproduce your problem](http://coliru.stacked-crooked.com/a/9abbe27406d74367). What error did you get? What are you trying to do? – WhiZTiM Jan 20 '17 at 09:48
  • I guess `act_with_params` is actually `funct_with_params`, but how and where did you declare `param1` and `param2`? Please provide a [mcve]. – Quentin Jan 20 '17 at 09:49
  • 1
    which compiler? – stefaanv Jan 20 '17 at 09:56
  • I am using clang, I think it might be a compiler issue. – cerkiewny Jan 20 '17 at 10:06
  • First year of C++, you blame the CPU for messing up. Second year, you blame the compiler for bugging. Third year, it's the standard library. Only after fourth year you begin to suspect your code to be wrong somehow. – YSC Jan 20 '17 at 10:24

1 Answers1

3

Problem is that type of action member variable in option is std::function<void(void)> and you are initializing option with different function (std::function<void(int &a, int &b)>). This is due to std::bind functioning (std::bind).

You need correct types. Also i might suggest, because you want to use constant vector, it would be better to use an std::array.

Code sample:

#include <functional>
#include <vector>
#include <array>

struct option {
    int num;
    std::string txt;
    std::function<void(int &a, int &b)> action;
};

void funct_with_params(int &a, int &b){
    a = 3; b = 4;
}


int main(){
    int param1 = 1;
    int param2 = 3;

    //vector fill
    const std::vector<option> choices{
        { 1, "sometext", std::bind(funct_with_params, std::ref(param1), std::ref(param2)) }
    };

    //array fill
    const std::array<option, 1> choices2 = {
        { 1, "sometext", std::bind(funct_with_params, std::ref(param1), std::ref(param2)) }
    };
    return 0;
}

Another solution would be using templates.

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • 1
    This makes no sense to me... Once both parameters are bound, the function is nullary. Yet you can indeed store it inside an `std::function` and call it with two more arguments, which are ignored. What the hell. – Quentin Jan 20 '17 at 10:44
  • Follow-up to my previous comment: this is [by design](http://stackoverflow.com/questions/16164769/understanding-stdfunction-and-stdbind). Unfortunately this answer is thus wrong: `std::function action` works and is what OP is after. – Quentin Jan 20 '17 at 10:57