Re: Functor Compilation Error
On Nov 3, 11:27 pm, BSand0...@msn.com wrote:
I'm getting an error that I can't seem to resolve. When I compile theFunctorrelated logic in a test program, the files compile and execute
properly (see Listing #1).
However, when I incorporate the same logic within my simulation, the
class that implements thefunctorlogic has problems compiling. I get
the following errors:
-- Building myTest.cpp --
In file included from myTest.cpp:52:
../tstDir/myFunctor.h:19: error: expected unqualified-id before '*'
token
../tstDir/myFunctor.h:19: error: expected `)' before '*' token
../tstDir/myFunctor.h:19: error: expected `,' or `...' before '*'
token
../tstDir/myFunctor.h:19: error: `TSpecificFunctor' declared as
function returning a function
../tstDir/myFunctor.h:19: error: `<anonymous>' has incomplete type
../tstDir/myFunctor.h:19: error: invalid use of `void'
../tstDir/myFunctor.h:19: error: expected `;' before ')' token
myTest.cpp: In member function `virtual void
tst::myTest::Initialize()':
myTest.cpp:527: error: no matching function for call to
`tst::TSpecificFunctor<tst::myScats>::TSpecificFunctor(tst::myScats*,
void (tst::myScats::*)())'
../tstDir/myFunctor.h:14: note: candidates are:
tst::TSpecificFunctor<tst::myScats>::TSpecificFunctor(const
tst::TSpecificFunctor<tst::myScats>&)
Listing #2 provides thefunctorimplementation as used in my
simulation. Can anyone tell me what is causing the compilation error
and how to possibly resolve it?
LISTING #2 (code in simulation)
In myTest.cpp:
#include "ScatFunctor.h"
#include "myScats.h"
#include "myFunctor.h"
void myTest::Initialize()
{
using namespace tst;
myScats objB;
TSpecificFunctor<myScats> specFunc( &objB, &myScats::Initialize);
myFunctor* funcTable[] = { &specFunc };
funcTable[0]->Call();
}
In myFunctor.h:
#ifndef myFunctor_H
#define myFunctor_H
#include "tst_config.h"
#include "ScatFunctor.h"
BEGIN_TST_NAMESPACE
template <class TClass> class TSpecificFunctor : public TFunctor
{
public:
// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
TSpecificFunctor(TClass* _pt2Object, void(TClass::_*fpt) ())
{ pt2Object = _pt2Object; fpt = _fpt; };
// override function "call" in base class
virtual void Call()
{ (*pt2Object.*fpt) (); };
private:
void (TClass::*fpt) ();
TClass* pt2Object;
};
END_TST_NAMESPACE
#endif
In ScatFunctor.h:
#ifndef ScatFunctor_H
#define ScatFunctor_H
#include "tst_config.h"
BEGIN_TST_NAMESPACE
class TFunctor
{
public:
virtual void Call(); // call using function
};
END_TST_NAMESPACE
#endif
In myScats.h:
#ifndef myScats_H
#define myScats_H
#include "tst_config.h"
BEGIN_TST_NAMESPACE
class myScats
{
public:
// Constructor/Destructor
myScats() {};
virtual ~myScats();
void Initialize() {"In Scats Initialize"};
protected:
private:
};
END_TST_NAMESPACE
#endif // End of Listing #2
LISTING #1 (stand-alone test program)
In BaseFunctor.cpp:
#include "BaseFunctor.h"
#include "DerivedFunctor.h"
#include "sea.h"
int main (int argc, char* argv[])
{
sea objB;
// instantiate DerivedFunctor objects ...
//functorencapsulating pointer to object and to a member of
class sea
TSpecificFunctor<sea> specFuncSea(&objB, &sea::Display);
// array with pointers to the Base class (TFunctor) and initialize
it
TFunctor *vT = { &specFuncSea };
vT->Call();
return 0;
}
In BaseFunctor.h:
#ifndef BaseFunctor_H
#define BaseFunctor_H
// abstract base class
class TFunctor
{
public:
// Derived classes will use a pointer to an object and
// a pointer to a member function to make the function call
virtual void Call()=0; //call using provided function name
};
#endif
In DerivedFunctor.h:
#ifndef TSpecificFunctor_H
#define TSpecificFunctor_H
#include "BaseFunctor.h"
template <class TClass> class TSpecificFunctor : public TFunctor
{
public:
// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
TSpecificFunctor(TClass* _pt2Object, void(TClass::*_fpt) ())
{ pt2Object = _pt2Object; fpt = _fpt; };
// override function "Call" in base class
virtual void Call() // executes member function
{ (*pt2Object.*fpt) (); };
private:
void (TClass::*fpt) (); // pointer to a member function
TClass* pt2Object; // pointer to an object
};
#endif
In Sea.h:
#ifndef sea_H
#define sea_H
#include <iostream>
using namespace std;
class sea
{
public:
sea() {};
// Sea's Functions
void Display() { cout << "In Sea Display" << endl; };
};
#endif
The above (LISTING #1) is compiled with the following script and
the resulting binary executes properly:
#/bin/sh
echo compiling C++ using -ansi -pedantic-errors -Wall -fPIC -g
g++ -ansi -pedantic-errors -Wall -Wno-deprecated -fPIC -g $1 $2 $3
Any help regarding some possible solutions for the compilation errors
would be greatly appreciated!
Danny
Thanks Alf!! Your suggestions / tips worked great! However, I now
have a secondary problem if you or anyone else could help me with. I
have the following code:
#ifndef MYFUNCTOR_H
#define MYFUNCTOR_H
#include "struct1.h"
#include "struct2.h"
class MyFunctor
{
public:
// No arg list
virtual void Call()=0; // call using function
// For multi args
virtual void Call_m(struct1*, struct2*, int, double)=0;
};
#endif
#ifndef TSTFUNCTOR_H
#define TSTFUNCTOR_H
#include "MyFunctor.h"
template <class TClass> class TSpecificFunctor : public MyFunctor
{
public:
// Constructor - takes pointer to an object and pointer to
// a member function and stores them in two private variables
// no arg list
TSpecificFunctor( TClass* _pt2Object, void(TClass::*tfpt) ())
{ pt2Object = _pt2Object; fpt = tfpt; };
// For Multi Args
TSpecificFunctor( TClass* _pt2Object, void(TClass::*tfpt)
(struct1*, struct2*,
int, double) )
{ pt2Object = _pt2Object; fpt = tfpt; };
// override function "call" in base class
// no arg list
virtual void Call()
{ (*pt2Object.*fpt) (); };
// For Multi Args
virtual void Call_m(struct1* bkgnd, struct2* geo, int val1,
double val2)
{ (*pt2Object.*fpt) (bkgnd, geo, val1, val2); };
private:
// For No Arguments
void (TClass::*fpt) ();
// For Multi Args
void (TClass::*fpt) (struct1*, struct2*, int, double);
TClass* pt2Object;
};
#endif
In Source Code (MyCode.cpp):
Land objLand;
TSpecificFunctor<Land> specFuncLand_0(&objLand, &Land::init_test);
TSpecificFunctor<Land> specFuncLand_1(&objLand, &LandS::init_test3);
ScatFunctor *funcTable[] = { &specFuncLand_0, &specFuncLand_1 };
// call test function (no arguments)
funcTable[0]->Call();
// call registered multi args function
funcTable[1]->Call_m(str1, str2, Val1, Val2);
When I compile and just use one of the constructors (e.g. the multi
argument case), all works well. However, when I add the no argument
case, I get the following compilation errors:
Errors during compilation:
TstFunctor.h:78: error: declaration of `void
(TClass::*TSpecificFunctor<TClass>::fpt)()'
TstFunctor.h:68: error: conflicts with previous declaration `void
(TClass::*TSpecificFunctor<TClass>::fpt)(struct1*, struct2*, int,
double)'
TstFunctor.h: In constructor
`TSpecificFunctor<TClass>::TSpecificFunctor(TClass*, void (TClass::*)
()) [with TClass = Land]':
MyCode.cpp:258: instantiated from here
TstFunctor.h:42: error: cannot convert `void (Land::*)()' to `void
(Land::*)(struct1*, struct2*, int, double)' in assignment
TstFunctor.h: In member function `void
TSpecificFunctor<TClass>::Call() [with TClass = Land]':
MyCode.cpp:2287: instantiated from here
TstFunctor.h:63: error: too few arguments to function
make[1]: *** [Mycode.o] Error 1
Is there a way to setup my classes to handle various argument lengths
for the functions I need to use (e.g. init_test, init_test3)? I
thought I could over-ride the constructors in TstFunctor.h, but either
I can't, or I'm not doing it correctly.
Thanks for any help / tips that can be provided.
Danny