проблемы с картами функций на с ++ - PullRequest
0 голосов
/ 15 ноября 2010

У меня проблемы с обработкой C ++ карт функций без ошибок.Я делаю простой Round Robin Scheduler, и есть некоторые переменные, например, сколько раз запускалась каждая программа и т. Д., Которые я хочу менять при каждом запуске, поэтому я создал деку указателей на функции, которые я буду выполнять, и когдафункция выскочила, я хочу получить ее «состояние» и изменить ее на карту, но это сложно.Мой код:

#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;

    }

Но этот код дает мне ошибки, которые я не могу расшифровать, например:

../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> 

И это действительно странно, это просто плохой подход?

../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

Кто-нибудь может мне помочь?

Ответы [ 5 ]

3 голосов
/ 15 ноября 2010

Это не то, как вы вставляете в std::map.Вам нужно сделать что-то вроде:

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

Могут быть и другие ошибки, но это первая, которую я увидел (и причина вашего первого сообщения компилятора).

2 голосов
/ 15 ноября 2010

Несколько выпусков:

1. Сравнимо ли время? Это должно быть как timeval может быть меньше, чем другой, но компилятор должен знать это. Есть ли

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

Если нет, вы можете написать функцию для их сравнения и использовать ее в качестве третьего параметра при создании карты.

2. Возможно, им следовало написать метод map.insert (ключ, значение), но они этого не сделали. Вышеупомянутый плакат предложил использовать оператор [], который будет вставлять, но есть разница: при использовании оператора [] он всегда будет перезаписывать, даже если ключ уже существует, и будет использовать конструктор по умолчанию для типа значения, а затем присваивать ему. Это, вероятно, не проблемы здесь. Другой вариант - использовать insert, в этом случае вы должны использовать times.insert( std::make_pair(key, value) );. Вы также можете добавить «подсказку» относительно того, куда добавить, таким образом times.insert( std::make_pair(key, value), times.end() );, хотя «end» является подсказкой по умолчанию, поэтому в этом случае нет реальной необходимости. , Вставка в карту - это O (log N), но если вы дадите точную подсказку о том, куда ее вставить, вы получите постоянное время.

3. pop_front () ничего не возвращает. Вам нужно вызвать front (), чтобы прочитать первый элемент, и pop_front (), чтобы просто удалить его. Это было сделано таким образом, чтобы не было побочных эффектов, если конструктор копирования генерирует и коллекция не покидает свое первоначальное состояние.

2 голосов
/ 15 ноября 2010

1) insert requres std :: pair

2) pop_back возвращает void, поэтому он не выполняет то, о чем вы думали

1 голос
/ 15 ноября 2010

Доступ к картам менее запутан, если вы используете оператор []:

exec[i1] = &f1;
0 голосов
/ 15 ноября 2010

Это почти сделано:

#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;
}

Как видите, вы должны реализовать оператор <для временных объектов, который необходим для std :: map. </p>

Во-вторых, вы неправильно используете insert () и pop_front (), прочитайте документацию по C ++.

Последнее: functions.front () возвращает указатель на функцию, как вы должны использовать ее в качестве ключа для startMap?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...