1

I am trying to store function pointers in a map, along with a structure. The idea is to execute the corresponding functions, when I find specific values in the structure. The program is not compiling, and giving me lot of errors when I am trying to insert data into the map through std::make_pair. Here is the code that I have written. Please guide me as to what I am doing wrong here..

#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>

struct _timeset
{
    int hr1;
    int min1;
    int secs1;
};

_timeset t1 = { 17, 10, 30 };

void fun1(void)
{
    std::cout << "inside fun1\n";
}

void fun2(void)
{
    std::cout << "inside fun2\n";
}

void fun3(void)
{
    std::cout << "inside fun3\n";
}

std::map<_timeset, void(*)()> m1;

int main()
{
    m1.insert(std::make_pair(t1, fun1));  //Compiling errors here



    return 0;
}

My basics in STL is very poor. I am using VS2013 Compiler. Also while iterating the map, can I execute the relevant function with something like :

std::map<_timeset, void(*)()>::iterator it1;
    int i = 0;
    for (i=0,it1 = m1.begin(); it1 != m1.end(); it1++,i++)
    {

        _timeset _t = it1->first;
         //Check Values in _t, and then execute the corresponding function in the map

            (*it1->second)();
    }

many thanks,

XMarshall
  • 953
  • 3
  • 11
  • 23
  • 1
    If you have compiler errors you should include them in the question. – NathanOliver Dec 11 '15 at 15:28
  • 4
    map keys (`_timeset` in your case) should have `operator<` defined for them. – SergeyA Dec 11 '15 at 15:28
  • not enough space for all the errors – XMarshall Dec 11 '15 at 15:37
  • 2
    1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator <(const std::tuple<_Types...> &,const std::tuple<_Types1...> &)' : could not deduce template argument for 'const std::tuple<_Types...> &' from 'const _timeset' – XMarshall Dec 11 '15 at 15:39
  • Please **edit** your question and place some of the error messages in your question. Look at your comment, is it easily readable? – Thomas Matthews Dec 11 '15 at 16:05
  • 1
    BTW, the `typedef` keyword is very useful with function pointers. The `typedef` can be more readable than the function pointer syntax (and less typing). – Thomas Matthews Dec 11 '15 at 16:07

1 Answers1

4

You need to specify comparator for _timeset for std::map to work, for example:

struct _timeset
{
    int hr1;
    int min1;
    int secs1;
    bool operator<( const _timeset &t ) const {
        return std::make_tuple( hr1, min1, secs1 ) < std::make_tuple( t.hr1, t.min1, t.secs1 );
    }
};

or you can make it as lamba as described here

Also while iterating the map, can I execute the relevant function with something like

yes you can, also you do not have to copy your struct _timeset:

int i = 0;
for ( it1 = m1.begin(); it1 != m1.end(); it1++,i++)
{

    const _timeset &_t = it1->first;
     //Check Values in _t, and then execute the corresponding function in the map

        (*it1->second)();
}

if you want to store functions with different signature, use std::function:

typedef std::function<void()> func;
std::map<_timeset, func> m1;

void fun1();
void func2( int );
struct foobar { void func3(); };

m1.insert( std::make_pair( t, func1 ) ); // signature matches, no need for bind
m1.insert( std::make_pair( t, std::bind( func2, 123 ) ) ); // signature does not match func2(123) will be called
foobar *pf = ...;
m1.insert( std::make_pair( t, std::bind( func3, pf ) ) ); // signature does not match, pf->func3() will be called
// etc
Community
  • 1
  • 1
Slava
  • 43,454
  • 1
  • 47
  • 90
  • One small question though. How should I declare my map, if I want to hold various functions have different signatures? For example, my map now holds functions of type: void func(), and if I want to store functions of type int func(int) or string func(int), etc. Is there any generic solution for declaring my map which would hold all function types?? Probably templates are the only solution. Any example would be very nice.Thanks – XMarshall Dec 11 '15 at 17:55
  • 1
    @XMarshall use `std::function` and `std::bind`, see updated example – Slava Dec 11 '15 at 17:58
  • std::function and std::bind is not available in VS2013 compiler? – XMarshall Dec 11 '15 at 18:00
  • 2
    not sure about VS2013, it is available since C++11, you can use boost instead if your compiler does not support C++11. Usage is the same except `boost` namespace instead of `std` and namespace for placeholders in `std` – Slava Dec 11 '15 at 18:05
  • 1
    std::function and std::bind are definitely available for VS2013. Make sure you `#include ` – Jonathan Wakely Dec 11 '15 at 18:41
  • Thanks Jonathan and Slava – XMarshall Dec 12 '15 at 21:31