Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Błąd kompilacji na nowej bibliotece boost

Ostatnio zmodyfikowano 2021-06-05 13:17
Autor Wiadomość
Temat założony przez niniejszego użytkownika
Błąd kompilacji na nowej bibliotece boost
» 2021-06-04 23:47:09
Witam
Posiadam dosyć stary kod źródłowy silnika gry open tibia server na bazowym cvs z 2005 roku, kompilacje przeprowadzam na systemie debian 10 z użyciem boosta 1.67, jako że kilka lat temu robiłem tą samą kompilacje ale na starszej bibliotece boost, linijka wskazana przez kompilator została przezemnie opisana komentarzem, ten problem nie występował, proszę o pomoc w rozwiązaniu problemu.
game.h: In member function ‘virtual void TCallList<ArgType>::operator()(Game*)’:
game.h:738:16: error: expression cannot be used as a function

C/C++
template < class ArgType >
class TCallList
    : public SchedulerTask
{
public:
   
TCallList(
   
boost::function < bool( Game *, ArgType ) > f1,
   
Task * f2,
   
std::list < ArgType > & call_list,
   
int64_t interval )
        :
_f1( f1 )
       
, _f2( f2 )
       
, _list( call_list )
       
, _interval( interval )
   
{
       
//
   
}
   
   
virtual void operator()( Game * arg )
   
{
       
if( _eventid != 0 ) {
           
bool ret = _f1( arg, _list.front() );
           
_list.pop_front();
           
           
if( ret ) {
               
if( _list.empty() ) {
                   
//callback function
                   
if( _f2 ) {
                       
( _f2 )( arg ); // linijka 738 którą wskazuje kompilator
                       
delete _f2;
                   
}
                }
               
else {
                   
//fire next task
                   
SchedulerTask * newTask = new TCallList( _f1, _f2, _list, _interval );
                   
newTask->setTicks( _interval );
                   
newTask->setEventId( this->getEventId() );
                   
arg->addEvent( newTask );
               
}
            }
        }
    }
   
private:
   
boost::function < bool( Game *, ArgType ) > _f1;
   
Task * _f2;
   
   
std::list < ArgType > _list;
   
int64_t _interval;
};

template < class ArgType >
SchedulerTask * makeTask( int64_t ticks,
boost::function < bool( Game *, ArgType ) > * f1,
std::list < ArgType > & call_list,
int64_t interval,
Task * f2 )
{
   
TCallList < ArgType > * t = new TCallList < ArgType >( f1, f2, call_list, interval );
   
t->setTicks( ticks );
   
return t;
}

Z kolei funkcje zadeklarowane są w osobnym pliku cpp:
C/C++
#ifndef __OTSERV_SCHEDULER_H__
#define __OTSERV_SCHEDULER_H__

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <functional>
#include "otsystem.h"

class Game;

class SchedulerTask {
public:
   
SchedulerTask() {
       
_eventid = 0;
       
_cycle = 0;
   
}
   
   
virtual ~SchedulerTask()
   
{
       
//
   
}
   
   
// definition to make sure lower cycles end up front
    // in the priority_queue used in the scheduler
   
inline bool operator <( const SchedulerTask & other ) const
   
{
       
return getCycle() > other.getCycle();
   
}
   
   
virtual void operator()( Game * arg ) = 0;
   
   
virtual void setEventId( uint32_t id )
   
{
       
_eventid = id;
   
}
   
   
inline uint32_t getEventId() const
   
{
       
return _eventid;
   
}
   
   
virtual void setTicks( const int64_t ticks )
   
{
       
_cycle = OTSYS_TIME() + ticks;
   
}
   
   
inline int64_t getCycle() const
   
{
       
return _cycle;
   
}
   
protected:
   
uint32_t _eventid;
   
int64_t _cycle;
};

class TSchedulerTask
    : public SchedulerTask
{
public:
   
TSchedulerTask( boost::function1 < void, Game * > f )
        :
_f( f )
   
{
       
//
   
}
   
   
virtual ~TSchedulerTask()
   
{
       
//
   
}
   
   
virtual void operator()( Game * arg )
   
{
       
_f( arg );
   
}
   
protected:
   
boost::function1 < void, Game * > _f;
};

SchedulerTask * makeTask( boost::function1 < void, Game * > f );
SchedulerTask * makeTask( int64_t ticks, boost::function1 < void, Game * > f );

class lessSchedTask
    : public std::binary_function < SchedulerTask *, SchedulerTask *, bool >
{
public:
   
bool operator()( SchedulerTask * & t1, SchedulerTask * & t2 )
   
{
       
return * t1 < * t2;
   
}
}
;

#endif
P-178703
» 2021-06-04 23:56:32
game.h:738:16: error: expression cannot be used as a function
Jak wygląda linijka 738 oraz jak wygląda linijka, która wywołuje tą linijkę? Komunikat sugeruje, że linijka 738 to prawdopodobnie:
C/C++
virtual void operator()( Game * arg )

Niemniej jednak problemem może być wywołanie, a nie deklaracja operatora. Przykładowy błąd kompilacji w prostszym wydaniu:
https://stackoverflow.com/questions/21617609/error-expression-cannot-be-used-as-a-function/21617634
P-178704
Temat założony przez niniejszego użytkownika
» 2021-06-05 12:00:20
( _f2 )( arg );
 // linijka 738 którą wskazuje kompilator, jest to pod komentarzem: //callback function
Przy próbie zamiany na
( * _f2 )( arg );
 dostaję błąd z tej samej linijki lecz z inną treścia o deklaracji:
game.h:738:17: error: no match for call to ‘(Task) (Game*&)’
P-178705
» 2021-06-05 12:19:23
Powinno być
C/C++
( * _f2 )( arg ); // linijka 738 którą wskazuje kompilator

Przy próbie zamiany na ( * _f2 )( arg );
 dostaję błąd z tej samej linijki lecz z inną treścia o deklaracji:
game.h:738:17: error: no match for call to ‘(Task) (Game*&)’
A reszta treści błędu? Najlepiej podaj całe wyjście z kompilatora, z całego procesu kompilacji.
P-178706
Temat założony przez niniejszego użytkownika
» 2021-06-05 12:25:50
Proszę bardzo.
-Werror -Winvalid-pch -ggdb -g -std=c++11 -march=native -O2 -include "preheaders.h" -c houses.cpp
In file included from tasks.h:29,
                 from game.cpp:27:
game.h: In member function ‘virtual void TCallList<ArgType>::operator()(Game*)’:
game.h:738:17: error: no match for call to ‘(Task) (Game*&)’
       (*_f2)(arg);
                 ^
cc1plus: all warnings being treated as errors
make: *** [Makefile:24: game.o] Error 1
make: *** Waiting for unfinished jobs....
P-178707
» 2021-06-05 12:25:51
Zmontowałem kod, którym da się zreprodukować błąd bez boosta:
C/C++
#include <functional>
#include <list>

class Task { };
class Game { };

class SchedulerTask {
public:
   
SchedulerTask() {
       
_eventid = 0;
       
_cycle = 0;
   
}
   
   
virtual ~SchedulerTask()
   
{
       
//
   
}
   
   
// definition to make sure lower cycles end up front
    // in the priority_queue used in the scheduler
   
inline bool operator <( const SchedulerTask & other ) const
   
{
       
return getCycle() > other.getCycle();
   
}
   
   
virtual void operator()( Game * arg ) = 0;
   
   
virtual void setEventId( uint32_t id )
   
{
       
_eventid = id;
   
}
   
   
inline uint32_t getEventId() const
   
{
       
return _eventid;
   
}
   
   
virtual void setTicks( const int64_t ticks )
   
{
       
_cycle = ticks;
   
}
   
   
inline int64_t getCycle() const
   
{
       
return _cycle;
   
}
   
protected:
   
uint32_t _eventid;
   
int64_t _cycle;
};

class TSchedulerTask
    : public SchedulerTask
{
public:
   
TSchedulerTask( std::function < void( Game * ) > f )
        :
_f( f )
   
{
       
//
   
}
   
   
virtual ~TSchedulerTask()
   
{
       
//
   
}
   
   
virtual void operator()( Game * arg )
   
{
       
_f( arg );
   
}
   
protected:
   
std::function < void( Game * ) > _f;
};

template < class ArgType >
class TCallList
    : public SchedulerTask
{
public:
   
TCallList(
   
std::function < bool( Game *, ArgType ) > f1,
   
Task * f2,
   
std::list < ArgType > & call_list,
   
int64_t interval )
        :
_f1( f1 )
       
, _f2( f2 )
       
, _list( call_list )
       
, _interval( interval )
   
{
       
//
   
}
   
   
virtual void operator()( Game * arg )
   
{
       
if( _eventid != 0 ) {
           
bool ret = _f1( arg, _list.front() );
           
_list.pop_front();
           
           
if( ret ) {
               
if( _list.empty() ) {
                   
//callback function
                   
if( _f2 ) {
                       
( _f2 )( arg );
                       
delete _f2;
                   
}
                }
               
else {
                   
//fire next task
                   
SchedulerTask * newTask = new TCallList( _f1, _f2, _list, _interval );
                   
newTask->setTicks( _interval );
                   
newTask->setEventId( this->getEventId() );
                   
//arg->addEvent(newTask);
               
}
            }
        }
    }
   
private:
   
std::function < bool( Game *, ArgType ) > _f1;
   
Task * _f2;
   
   
std::list < ArgType > _list;
   
int64_t _interval;
};

int main()
{
   
std::function < bool( Game *, int ) > fn;
   
std::list < int > list;
   
TCallList < int > x( fn, nullptr, list, 0 );
   
return 0;
}
P-178708
» 2021-06-05 12:28:25
game.h:738:17: error: expression cannot be used as a function
       *(_f2)(arg);
Gwiazdka ma być wewnątrz nawiasu. I miałeś podać cały log z kompilacji, nie fragment ucięty do tego co uważasz za istotne dla problemu..
P-178709
» 2021-06-05 12:33:12
Pekfosa diagnoza jest poprawna. Co musi być spełnione, aby fix zadziałał:
C/C++
class Task {
public:
   
void operator()( Game * ) { } //task musi mieć operator
};

//...
if( _f2 ) {
   
( * _f2 )( arg ); //_f2 to Task*, więc musisz dostać się najpierw do Task&, a potem wywołać operator.
   
delete _f2;
}

Cały kod po fixie:
C/C++
#include <functional>
#include <list>

class Game { };

class Task {
public:
   
void operator()( Game * ) { } //task musi mieć operator
};

class SchedulerTask {
public:
   
SchedulerTask() {
       
_eventid = 0;
       
_cycle = 0;
   
}
   
   
virtual ~SchedulerTask()
   
{
       
//
   
}
   
   
// definition to make sure lower cycles end up front
    // in the priority_queue used in the scheduler
   
inline bool operator <( const SchedulerTask & other ) const
   
{
       
return getCycle() > other.getCycle();
   
}
   
   
virtual void operator()( Game * arg ) = 0;
   
   
virtual void setEventId( uint32_t id )
   
{
       
_eventid = id;
   
}
   
   
inline uint32_t getEventId() const
   
{
       
return _eventid;
   
}
   
   
virtual void setTicks( const int64_t ticks )
   
{
       
_cycle = ticks;
   
}
   
   
inline int64_t getCycle() const
   
{
       
return _cycle;
   
}
   
protected:
   
uint32_t _eventid;
   
int64_t _cycle;
};

class TSchedulerTask
    : public SchedulerTask
{
public:
   
TSchedulerTask( std::function < void( Game * ) > f )
        :
_f( f )
   
{
       
//
   
}
   
   
virtual ~TSchedulerTask()
   
{
       
//
   
}
   
   
virtual void operator()( Game * arg )
   
{
       
_f( arg );
   
}
   
protected:
   
std::function < void( Game * ) > _f;
};

template < class ArgType >
class TCallList
    : public SchedulerTask
{
public:
   
TCallList(
   
std::function < bool( Game *, ArgType ) > f1,
   
Task * f2,
   
std::list < ArgType > & call_list,
   
int64_t interval )
        :
_f1( f1 )
       
, _f2( f2 )
       
, _list( call_list )
       
, _interval( interval )
   
{
       
//
   
}
   
   
virtual void operator()( Game * arg )
   
{
       
if( _eventid != 0 ) {
           
bool ret = _f1( arg, _list.front() );
           
_list.pop_front();
           
           
if( ret ) {
               
if( _list.empty() ) {
                   
//callback function
                   
if( _f2 ) {
                       
( * _f2 )( arg ); //Fix jak pekfos napisał
                       
delete _f2;
                   
}
                }
               
else {
                   
//fire next task
                   
SchedulerTask * newTask = new TCallList( _f1, _f2, _list, _interval );
                   
newTask->setTicks( _interval );
                   
newTask->setEventId( this->getEventId() );
                   
//arg->addEvent(newTask);
               
}
            }
        }
    }
   
private:
   
std::function < bool( Game *, ArgType ) > _f1;
   
Task * _f2;
   
   
std::list < ArgType > _list;
   
int64_t _interval;
};

int main()
{
   
std::function < bool( Game *, int ) > fn;
   
std::list < int > list;
   
TCallList < int > x( fn, nullptr, list, 0 );
   
return 0;
}
P-178710
« 1 » 2
  Strona 1 z 2 Następna strona