|
I think I need a bit more information. Can you provide an
example of how Dump_List_Element is actually used
by Dump_List and also how Dump_List is instantiated?
Does your application have a specialization of
Dump_List_Element(ArgumentSpecHandle&, void*) at all?
Thanks,
Lois D. Foltan
DEC C++ Development
|
| Lois,
both Dump_List and Dump_List_Element are instantiated for at least 5 classes
(for the time being, manually).
Here the contents of Dump_List.hxx :
====================================
#ifndef _DUMP_THINGS_HXX_
#define _DUMP_THINGS_HXX_
#include <rw/tvslist.h>
class Dump_RWTValList_Arg
{
public:
const char * pref_;
const int lvl_;
Dump_RWTValList_Arg(const char *p, const int i) : pref_(p),lvl_(i) {};
};
template <class SomeHandle>
void Dump_List_Element
(SomeHandle & element,
void * arg)
{
Dump_RWTValList_Arg *dump_arg = (Dump_RWTValList_Arg *)arg;
element.dumpThis(dump_arg->pref_, dump_arg->lvl_);
}
template <class SomeHandle>
void Dump_List
(const RWTValSlist<SomeHandle> & list,
const char * pref,
const int lvl)
{
Dump_RWTValList_Arg dump_arg (pref, lvl);
RWTValSlist<SomeHandle> tmp;
tmp = list;
if (list.entries())
tmp.apply (Dump_List_Element, (void *)&dump_arg);
else
cout << pref << " is an empty list." << endl;
// The following seems to be needed to instantiate the template
//
//if (0) Dump_List_Element(SomeHandle(), (void *)0);
//
// we changed it by #pragma define_template in the appropriate .cxx file
//
}
#endif /* _DUMP_THINGS_HXX_ */
Here an extract from a (test) program :
=======================================
arg.setVariableName ("dismissed");
a.addArgumentSpec (arg); // a contans a list of ArgumentSpec
a.dumpThis("a",FULL_DUMP); // this dumps a, including the list
Here the code of a.dumpThis() :
===============================
void EventSpecHandle::dumpThis (const char *arg, const int lvl) const
{
const char *pref, *classname = "::EventSpec.";
if (arg) pref = arg;
else pref = "";
cout << pref << classname << "rep_ = " << rep_ ;
if (rep_)
{
cout << " refcount = " << rep_->getRefCount() << endl;
if (lvl == DUMP_REP_ONLY) return;
cout << pref << classname << "name_ = " << rep_->name_ <<
endl;
cout << pref << classname << "variableName_ = " << rep_->variableName_ <<
endl;
cout << pref << classname << "sign_ = " << rep_->sign_ <<
endl;
cout << pref << classname << "comment_ = " << rep_->comment_ <<
endl;
RWCString tmp(pref); tmp += classname;
tmp += "argumentSpecs_";
Dump_List (rep_->argumentSpecs_, (const char *)tmp,
DUMP_PROPAGATE_lvl(lvl));
}
else
cout << endl;
}
#pragma define_template compareKey<EventSpecHandle>
#pragma define_template Dump_List<EventSpecHandle>
#pragma define_template Dump_List_Element<EventSpecHandle>
The 3 pragma's are not for ArgumentSpec but for EventSpec; EventSpec contains
a list of ArgumentSpec. Some other objects contain a list of EventSpec, that
is why I instantiate the 3 functions on EventSpec. ArgumentSpec.cxx contains a
similar constuction, that's what templates are about, no ?
As I said in my note, Dump_List is instantiated automatically.
Dump_List_Element is NOT. The compiler gives me error messages, in case the
signature of the template for Dump_List_Element does not match what is needed.
The only difference the I notcie is that the code contains a real call to
Dump_List while it does not contain one to Dump_List_Element. Only the address
of the function is used.
The function compareKey has a similar problem. Also, the code does not contain a
call to that function, only it's address is passed into the RogueWave library.
Thanks for looking at my problem,
dirk
|
| Hi Lois,
I have made a tar file of /usr/include/rw with lots of things in it.
The starting point are the files
tvslist.h
tvslist.cc
Then it starts including the whole world, xvslist, rwslist...
The documentation is on http://mybaby.vbo.dec.com/rogue/toolscr/classref.htm
if that would be of any use.
Dirk
|
| Lois,
cut along the ============ lines into the filenames indicated, then do the
folloing build procedure:
rm *.o
rm -R cxx_repository
cxx -Hf SimpleBuffer.cxx
cxx -Hf DifferentBuffer.cxx
cxx -Hf function_pointers.cxx
cxx -o function_pointers *.o
The answer I get is:
ld:
Unresolved:
func(SimpleBuffer&, void*)
func(DifferentBuffer&, void*)
From where my question in .0 "what am I doing wrong ?"
Dirk
========================== templates.hxx ================================
#ifndef _TEMPLATES_
#define _TEMPLATES_
#include <iostream.h>
struct Counter
{
char letter;
unsigned count;
};
template <class T>
void callforw (T & thing)
{
if (thing.letters_to_be_counted)
{
struct Counter arg;
char * l;
for (l = thing.letters_to_be_counted; *l; l++)
{
arg.letter = *l;
arg.count = 0;
thing.apply (func, (void *)&arg);
cout << "There are " << arg.count
<< " " << *l << "'s in thing" <<endl;
}
}
}
template <class T>
void func (T & thing, void *arg)
{
struct Counter * real_arg = (struct Counter *)arg;
char * p;
for (p = thing.buffer; p && *p; p++)
{
if (*p == real_arg->letter) real_arg->count += 1;
}
}
#endif
========================== SimpleBuffer.hxx ================================
#include "templates.hxx"
class SimpleBuffer
{
public:
char buffer[100];
char * letters_to_be_counted;
void apply (void (* f)(SimpleBuffer &, void *), void *);
};
class OtherBuffer : public SimpleBuffer
{
public:
int some;
float other;
struct Counter fields;
};
========================== SimpleBuffer.cxx ================================
#include "SimpleBuffer.hxx"
#include "templates.hxx"
void SimpleBuffer::apply (void (* f)(SimpleBuffer &, void *),
void *arg)
{
f (*this, arg);
}
========================== DifferentBuffer.hxx ================================
#include "templates.hxx"
class DifferentBuffer
{
public:
int total_count;
char * letters_to_be_counted;
char * letters_to_be_ignored;
char buffer[100];
void apply (void (* f)(DifferentBuffer &, void *), void *);
};
========================== DifferentBuffer.cxx ================================
#include "DifferentBuffer.hxx"
#include "templates.hxx"
void DifferentBuffer::apply (void (* f)(DifferentBuffer &, void *),
void *arg)
{
f (*this, arg);
}
========================= function_pointers.cxx ==============================
#include <iostream.h>
#include <string.h>
#include "SimpleBuffer.hxx"
#include "DifferentBuffer.hxx"
#define VOWELS "aeiouy"
main()
{
SimpleBuffer simple;
OtherBuffer other;
DifferentBuffer different;
strcpy (simple.buffer, "some simple string");
simple.letters_to_be_counted = VOWELS;
strcpy (other.buffer, "abcdefghijklmnopqrstuvwxyz");
other.letters_to_be_counted = VOWELS;
strcpy (different.buffer, "abcdefghijklmnopqrstuvwxyz");
different.letters_to_be_counted = "az";
// callforward is gently overloaded by the compiler using the template
// function declared earlier.
//
// callforw (simple, "simple"); will fail
callforw (simple);
callforw (other);
callforw (different);
}
|