Generate dictionary for list of custom classes

Hello ROOTers,

I have the following simple classes:

#include “TString.h”

class Datafile {
TString filename;
TString author;

typedef std::list DatafileList;
typedef std::map<Int_t, DatafileList> Dataset;

I’m trying to generate CINT dictionaries for them, but I can’t get DatafileList to work:

[code]$ root

  •                                     *
  •    W E L C O M E  to  R O O T       *
  •                                     *
  • Version 5.30/04 8 November 2011 *
  •                                     *
  • You are welcome to visit our Web site *
  •            *
  •                                     *

ROOT 5.30/04 (branches/v5-30-00-patches@41803, Nov 10 2011, 16:45:00 on linuxx8664gcc)

CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .L DatasetLibrary.C+
root [1] gInterpreter->GenerateDictionary(“Datafile”,“DatasetLibrary.h”)
Warning in TClassTable::Add: class Datafile already in TClassTable
root [2] gInterpreter->GenerateDictionary(“DatafileList”,“DatasetLibrary.h”)
In file included from /usr/include/c++/4.6/list:65:0,
from /home/dmancusi/.rootmacros/DatasetLibrary.h:2,
from /home/dmancusi/.rootmacros/AutoDict_DatafileList.cxx:1,
from /home/dmancusi/.rootmacros/AutoDict_DatafileList_cxx_ACLiC_dict.h:34,
from /home/dmancusi/.rootmacros/AutoDict_DatafileList_cxx_ACLiC_dict.cxx:17:
/usr/include/c++/4.6/bits/list.tcc: In member function ‘void std::list<_Tp, _Alloc>::remove(const value_type&) [with _Tp = Datafile, _Alloc = std::allocator, std::list<_Tp, _Alloc>::value_type = Datafile]’:
/home/dmancusi/.rootmacros/AutoDict_DatafileList_cxx_ACLiC_dict.cxx:643:107: instantiated from here
/usr/include/c++/4.6/bits/list.tcc:249:4: error: no match for ‘operator==’ in ‘__first.std::_List_iterator<_Tp>::operator* with _Tp = Datafile, std::_List_iterator<_Tp>::reference = Datafile& == __value’
/usr/include/c++/4.6/bits/list.tcc:249:4: note: candidates are:
// snipping the rest of the log, full log included as an attachment

Am I doing something obviously wrong?

Using ROOT 5.30/04.

debug.txt (16.9 KB)

Hi Davide,

The default for ACLiC (which you invoke viaroot [0] .L DatasetLibrary.C+) is to generate the dictionary for all symbols declared in the file and its header file (as in an include file that as the same name but an ‘header’ file extension).

/home/dmancusi/.rootmacros/AutoDict_DatafileList_cxx_ACLiC_dict.cxx:643:107: instantiated from here /usr/include/c++/4.6/bits/list.tcc:249:4: error: no match for ‘operator==’ in ‘__first.std::_List_iterator<_Tp>::operator* [with _Tp = Datafile, std::_List_iterator<_Tp>::reference = Datafile&]() == __value’ For full support of the std::list functionality you need to implement operator== for your class.



Thanks for the help. I actually had to define both operator== and operator<. Unfortunately, ROOT now crashes with the following message:

Warning in <TClassTable::Add>: class Datafile already in TClassTable Fatal: sizeof(::list<Datafile,allocator<Datafile> >::iterator) == sizeof(::ROOT::Shadow::listlEDatafilecOallocatorlEDatafilegRsPgR::iterator) violated at line 92 of `/home/dmancusi/.rootmacros/AutoDict_DatafileList_cxx_ACLiC_dict.cxx' aborting #0 0x00007f0765cb8eee in __libc_waitpid (pid=<optimized out>, stat_loc=0x7fff58a7c0ac, options=<optimized out>) at ../sysdeps/unix/sysv/linux/waitpid.c:32 #1 0x00007f0765c51a29 in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:149 #2 0x00007f0767d7d510 in TUnixSystem::StackTrace() () from /usr/lib/root/ #3 0x00007f0767ccaba2 in DefaultErrorHandler(int, bool, char const*, char const*) () from /usr/lib/root/ #4 0x00007f0767ccb07e in ErrorHandler () from /usr/lib/root/ #5 0x00007f0767ccb592 in Fatal(char const*, char const*, ...) () from /usr/lib/root/ #6 0x00007f075f21e3b0 in ROOT::GenerateInitInstanceLocal () from /home/dmancusi/.rootmacros/ #7 0x00007f075f21b787 in _GLOBAL__sub_I_AutoDict_DatafileList_cxx_ACLiC_dict.cxx () from /home/dmancusi/.rootmacros/ #8 0x00007f07684decd0 in ?? () from /lib64/ #9 0x00007f07684dedc7 in ?? () from /lib64/ #10 0x00007f07684e3183 in ?? () from /lib64/ #11 0x00007f07684de926 in ?? () from /lib64/ #12 0x00007f07684e289a in ?? () from /lib64/ #13 0x00007f076694ff66 in dlopen_doit (a=<optimized out>) at dlopen.c:67 #14 0x00007f07684de926 in ?? () from /lib64/ #15 0x00007f07669502ec in _dlerror_run (operate=0x7f076694ff00 <dlopen_doit>, args=0x7fff58a7e990) at dlerror.c:164 #16 0x00007f076694fee1 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:88 #17 0x00007f0767313976 in G__dlopen () from /usr/lib/root/ #18 0x00007f0767313dd1 in G__shl_load () from /usr/lib/root/ #19 0x00007f076728c46d in G__loadfile () from /usr/lib/root/ #20 0x00007f0767d42b47 in TCint::Load(char const*, bool) () from /usr/lib/root/ #21 0x00007f0767d0dd12 in TSystem::Load(char const*, char const*, bool) () from /usr/lib/root/ #22 0x00007f0767d131e6 in TSystem::CompileMacro(char const*, char const*, char const*, char const*, unsigned int) () from /usr/lib/root/ #23 0x00007f0767d49fad in TCint_GenerateDictionary(std::vector<std::string, std::allocator<std::string> > const&, std::vector<std::string, std::allocator<std::string> > const&, std::vector<std::string, std::allocator<std::string> > const&, std::vector<std::string, std::allocator<std::string> > const&) () from /usr/lib/root/ #24 0x00007f0767d4ad91 in TCint::GenerateDictionary(char const*, char const*, char const*) () from /usr/lib/root/ #25 0x00007f075f632999 in getDDXSDataset(ParticleType, double, int, int, ParticleType, double) () from /home/dmancusi/.rootmacros/ #26 0x00007f075f6334ff in G__DatasetLibrary_C_ACLiC_dict__0_2249(G__value*, char const*, G__param*, int) () from /home/dmancusi/.rootmacros/ #27 0x00007f07671f22d6 in Cint::G__ExceptionWrapper(int (*)(G__value*, char const*, G__param*, int), G__value*, char*, G__param*, int) () from /usr/lib/root/ #28 0x00007f07672968e1 in G__execute_call () from /usr/lib/root/ #29 0x00007f0767296c9e in G__call_cppfunc () from /usr/lib/root/ #30 0x00007f07672749f2 in G__interpret_func () from /usr/lib/root/ #31 0x00007f0767264074 in G__getfunction () from /usr/lib/root/ #32 0x00007f076723e0f9 in G__getitem () from /usr/lib/root/ #33 0x00007f0767244016 in G__getexpr () from /usr/lib/root/ #34 0x00007f07672c6335 in G__exec_statement () from /usr/lib/root/ #35 0x00007f076722a2d0 in ?? () from /usr/lib/root/ #36 0x00007f076722ba7e in G__exec_tempfile_fp () from /usr/lib/root/ #37 0x00007f07672d27d2 in G__process_cmd () from /usr/lib/root/ #38 0x00007f0767d48e9a in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /usr/lib/root/ #39 0x00007f0767cb33f9 in TApplication::ProcessLine(char const*, bool, int*) () from /usr/lib/root/ #40 0x00007f0766b65d39 in TRint::HandleTermInput() () from /usr/lib/root/ #41 0x00007f0767d7ed6c in TUnixSystem::CheckDescriptors() () from /usr/lib/root/ #42 0x00007f0767d804c6 in TUnixSystem::DispatchOneEvent(bool) () from /usr/lib/root/ #43 0x00007f0767d07246 in TSystem::InnerLoop() () from /usr/lib/root/ #44 0x00007f0767d08df4 in TSystem::Run() () from /usr/lib/root/ #45 0x00007f0767cb17df in TApplication::Run(bool) () from /usr/lib/root/ #46 0x00007f0766b66717 in TRint::Run(bool) () from /usr/lib/root/ #47 0x00000000004010bc in main ()


Add #ifdef __MAKECINT__ #pragma link C++ class list<Datafile>::iterator-; #endif // __MAKECINT__to you header file.


Hi Philippe,

I put the lines you suggested in my header, AFTER the Datafile and DatafileList declaration. That makes these types work, but not the Dataset type (the typedef’d map). I had to add the following #pragma directive to the header:

Shouldn’t these directives be automatically generated?

Thanks for the help!

Hi Davide,

[quote}Shouldn’t these directives be automatically generated?[/quote]Not necessarily. Since the std::map is not explicitly defined/declared in the header, whether or not the dictionary is generated depend on some idiosyncrasy of how CINT instantiate templates.