简体   繁体   中英

problems with maps of functions on c++

I'm having problems having C++ handle maps of functions without giving me errors. I'm making a simple Round Robin Scheduler and there are some variables like how many times each program has run etc. That I want changed at each run, so I created a deque of pointers to the functions that I will be running, and when a functions is popped I want to gets its 'state' and modify it to a map, but this is being difficult. My code is:

#include <map>
#include <iostream>
#include <ctime>
#include <sys/time.h>
#include <queue>
#include <string>
using namespace std;
int f1(string file);
int f2(string file);
int f3(string file);
int f4(string file);
int sendpacket(string echoString);
int i1=0, i2=0, i3=0, i4=0, i5=0;

int kf(void){
 return i1+i2+i3+i4+i5;
}


int main(int argc, char *argv[]){


/*
 cout << "How many times do you want to run each function?" << endl;
 int n;
 cin >> n;
  */
 typedef int (*ptof)(string);
 int n = 1000;
 timeval begin, end, tf1, tf2, tf3, tf4, tf5;


 //Setting up queue of functions
 deque<ptof> functions;
 functions.push_back(f1);
 functions.push_back(f2);
 functions.push_back(f3);
 functions.push_back(f4);
 functions.push_back(sendpacket);
 map<timeval, ptof> times;
 times.insert(tf1,f1);
 times.insert(tf2,f2);
 times.insert(tf3,f3);
 times.insert(tf4,f4);
 times.insert(tf5,sendpacket);
 map<int,ptof> exec;
 exec.insert(i1,f1);
 exec.insert(i2,f2);
 exec.insert(i2,f2);
 exec.insert(i3,f3);
 exec.insert(i4,f4);
 exec.insert(i5,sendpacket);
 map<int,ptof> startTimes;
 startTimes.insert(1000, f1);
 startTimes.insert(500, f2);
 startTimes.insert(150, f3);
 startTimes.insert(50, f4);
 startTimes.insert(0, sendpacket);
 //beginning scheduling

 gettimeofday(&begin, NULL);
 ptof p;
 int k=0;
 while(k<=5000){
  p = functions.pop_front();
  if(k>startTimes[p]){
                //Scheduler Code
  }

  k = kf();
 }


 gettimeofday(&end, NULL);
 double t1=begin.tv_sec+(begin.tv_usec/1000000.0);
 double t2=end.tv_sec+(end.tv_usec/1000000.0);
 double elapsed = t2-t1;
 cout << elapsed << " seconds elapsed\n" << endl;
 return 0;

    }

But this code gives me errors that I can't decipher, like:

../simpleRR.cpp:39: error: no matching function for call to 'std::map<timeval, int (*)(std::string), std::less<timeval>, std::allocator<std::pair<const timeval, int (*)(std::string)> > >::insert(timeval&, int (&)(std::string))'
/usr/include/c++/4.2.1/bits/stl_map.h:399: note: candidates are: std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> 

And these are really bizarre, is this just a bad approach?

../simpleRR.cpp:63: error: void value not ignored as it ought to be
../simpleRR.cpp:64: error: invalid conversion from 'int (*)(std::string)' to 'int'
../simpleRR.cpp:64: error:   initializing argument 1 of '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int (*)(std::string), _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int (*)(std::string)> >]'
../simpleRR.cpp:64: error: ISO C++ forbids comparison between pointer and integer

Can anybody help me out?

That is not how you insert into a std::map . You need to do something like:

startTimes.insert(std::pair<int,ptof>(1000,f1));

There may be other errors, but this is the first one I saw (and the cause of your first compiler message).

1) insert requres std::pair

2) pop_back returns void, therefore it doesn't do what you thought it does.

Several issues:

1 . Is timeval comparable? It should be as a timeval can be less than another one, but the compiler needs to know that. Is there a

bool operator<( const timeval &, const timeval& );

If not you can write a function to compare them and use that as the 3rd parameter when you create the map.

2 . Perhaps they should have written a method map.insert(key,value) but they didn't. The above poster suggested using operator[] which will insert but there is a difference: Using operator[] it will always overwrite, even if the key already exists, and it will use the default constructor for the value type and then assign to it. These are probably not issues here. Your other option is to use insert in which case you should use times.insert( std::make_pair(key, value) ); You can also add a "hint" as to where to add thus times.insert( std::make_pair(key, value), times.end() ); although "end" is the default hint so there is no real need in this case. Insertion into a map is O(log N) but if you give the exact hint as to where to insert it reduces to constant time.

3 . pop_front() doesn't return anything. You need to call front() to read the first element and pop_front() to simply remove it. It was done this way so that there would be no side-effect if the copy-constructor throws and the collection is not left its original state.

如果使用operator [],则访问地图的混乱程度较小:

exec[i1] = &f1;

This is almost done:

#include <map>
#include <iostream>
#include <ctime>
#include <sys/time.h>
#include <queue>
#include <string>

bool operator < (timeval const& lhs, timeval const& rhs)
{
    return lhs.tv_sec == rhs.tv_sec ?
        lhs.tv_usec < rhs.tv_usec :
        lhs.tv_sec < rhs.tv_sec;    
}

using namespace std;
int f1(string file);
int f2(string file);
int f3(string file);
int f4(string file);
int sendpacket(string echoString);
int i1=0, i2=0, i3=0, i4=0, i5=0;

int kf(void){
 return i1+i2+i3+i4+i5;
}


int main(int argc, char *argv[]) {
/*
 cout << "How many times do you want to run each function?" << endl;
 int n;
 cin >> n;
  */
    typedef int (*ptof)(string);
    int n = 1000;
    timeval begin, end, tf1, tf2, tf3, tf4, tf5;

    //Setting up queue of functions
    deque<ptof> functions;
    functions.push_back(f1);
    functions.push_back(f2);
    functions.push_back(f3);
    functions.push_back(f4);
    functions.push_back(sendpacket);
    map<timeval, ptof> times;
    times[tf1]= f1;
    times[tf2]= f2;
    times[tf3]= f3;
    times[tf4]= f4;
    times[tf5]= sendpacket;
    map<int,ptof> exec;
    exec[i1] = f1;
    exec[i2] = f2;
    exec[i3] = f3;
    exec[i4] = f4;
    exec[i5] = sendpacket;
    map<int,ptof> startTimes;
    startTimes[1000] = f1;
    startTimes[500] = f2;
    startTimes[150] = f3;
    startTimes[50] = f4;
    startTimes[0] = sendpacket;
    //beginning scheduling

    gettimeofday(&begin, NULL);
    ptof p;
    int k=0;
    while(k <= 5000) {
        p = functions.front();
        functions.pop_front();
        if(k > startTimes[p]){
            //Scheduler Code
        }
        k = kf();
    }

    gettimeofday(&end, NULL);
    double t1=begin.tv_sec+(begin.tv_usec/1000000.0);
    double t2=end.tv_sec+(end.tv_usec/1000000.0);
    double elapsed = t2-t1;
    cout << elapsed << " seconds elapsed\n" << endl;

    return 0;
}

As you see, you have to implement a operator< for timeval objects, that's needed for std::map.

Second thing, your use of insert() and pop_front() is wrong, please read your C++ documentation.

Last thing: functions.front() returns a pointer to a function, how are you supposed to use as a key for startMap?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM