Using vector<vector<double>> or float in 5.22

Hi,
I’ve got some code that works fine under 5.27, and I need to see if it (or something similar) can work back in 5.22. Basically, I’m trying to make a vector<vector> (or float) written out as a branch. I use ACLIC to compile my .C file, and it contains early in the file the following:

#ifdef __MAKECINT__ #pragma link C++ class vector<vector<float> >+; #pragma link C++ class vector<vector<double> >+; #endif

The code that declares the Branch looks like the following:

TTree *t = new TTree ("testTree", "Test of the tree"); vector<vector<float> > info = vector<vector<float> >(); vector<vector<float> > *pinfo = &info; t->Branch("info", &pinfo);

When I run on Windows in 5.27 this works just fine - no errors (I don’t need the vector<vector> dict generation either, actually). However, when I’m running on Linux (lxplus), using root 5.22, I get some errors:

[code][lxplus308] root -b -q ROOTTest.cxx+


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 5.22/00j 23 April 2010 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      http://root.cern.ch            *
    
  •                                     *
    

ROOT 5.22/00j (branches/v5-22-00-patches@33102, May 03 2010, 18:59:00 on linux)

CINT/ROOT C/C++ Interpreter version 5.16.29, Jan 08, 2008
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0]
Processing ROOTTest.cxx+…
Info in TUnixSystem::ACLiC: creating shared library /afs/cern.ch/user/g/gwatts/testdir/15.6.10.4/./ROOTTest_cxx.so
Note: Link requested for undefined class vector<vector > (ignore this message) :0:
Note: Link requested for undefined class vector<vector > (ignore this message) :0:
Error: A dictionary has been requested for vector<vector > but there is no declaration!
Error: A dictionary has been requested for vector<vector > but there is no declaration!

Error in TTree::Branch: The pointer specified for info is not of a class known to ROOT
Test 5 (2D vector of vector, variable size): 0.4 (rt:0.405116) - count 1807188
Error in TTree::Branch: The pointer specified for info is not of a class known to ROOT
Test 6 (2D vector of vector of float, variable size): 0.3 (rt:0.30529) - count 1806304
[/code]

So there are errors duing what I assume is the build part of the process (the not declared bits) and then there are the real errors - unknonw class errors.

What do I need to do to get this to work under 5.22? I’ve seen other references to this working post 5.20, but I can’t seem to get it right (I’ve tried ProcessLine("#include ") for example, but it doesn’t seem to change anything).

Thanks in advance!

Hi Gordon,

the #pragmas must come after the definition of the vector template. Do you #include before the #pragma?

Cheers, Axel.

Hi,
Thanks for the answer!

The #include is at the top of the file, the #pragma are in the middle of the file. At global scope I never declare a vector<vector<>> - those are always done inside a function. So I should put a dummy vector<vector<>> decl at the global scope in the file?

Cheers!

Ha! Found the problem - thanks, your answer started me down the right road. I had a “using std::vector” at the top of the file and then I had:

#ifdef __MAKECINT__ #pragma link C++ class vector<vector<float> >+; #pragma link C++ class vector<vector<double> >+; #endif

When I switched it over to

#ifdef __MAKECINT__ #pragma link C++ class std::vector<std::vector<float> >+; #pragma link C++ class std::vector<std::vector<double> >+; #endif

it worked just fine. So perhaps rootcint in 5.22 does not correctly deal with th std::vector… (I am using the template for of TTree::Branch). Or something else weird was happening in root that made it miss the fact that std::vector and using std::vector; vector were not the same thing.

Hi,
I have a follow-on question to this one in the same theme: can CINT in 5.22 deal with vector<vector>?

I take a root file with a single TTree in it, and in that a single branch that has vector<vector> in it, and write it out. I then load up the root file in a new version of root, run MakeClass on it. This produces a nice make class file with one branch which is listed as “vector<vector > info” in it. I then add “info->size()” to the .C file. At this point I can now do “.L test6.C+” and have it run just fine.

But if I instead use CINT via “.L test6.C” I get the error:

.root [0] .L test6.C root [1] t = new test6(); root [2] t.Loop() Error: Can't call vector<vector<float> >::size() in current scope test6.C:45: Possible candidates are... (in vector<vector<float> >) Size: (class G__CINT_ENDL)156391792 *** Interpreter error recovered *** root [3] .

Is that expected? I just want to make sure that I’m actually facing a CINT limitation here and not a gwatts limitation! :slight_smile:

Cheers!

Hi Gordon,

[quote]then I had: … vector<vector > … When I switched it over to … std::vector<std::vector > … it worked just fine[/quote]I can not reproduce this discrepancy:[code]$ cat loader.C
#include
#include
#ifdef MAKECINT
#pragma link C++ class vector<vector >+;
#pragma link C++ class vector<vector >+;
#endif
$ root.exe -b


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 5.22/00j 23 April 2010 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      http://root.cern.ch            *
    
  •                                     *
    

ROOT 5.22/00j (branches/v5-22-00-patches@33176, May 15 2010, 10:52:38 on linuxx8664gcc)

CINT/ROOT C/C++ Interpreter version 5.16.29, Jan 08, 2008
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .L loader.C+
root [1] TTree *t = new TTree (“testTree”, “Test of the tree”);
root [2] vector<vector > info = vector<vector >();
root [3] vector<vector > *pinfo = &info;
root [4] t->Branch(“info”, &pinfo);
root [5] [/code]

Cheers,
Philippe.

[quote]But if I instead use CINT via “.L test6.C” I get the error:

root [2] t.Loop()
Error: Can’t call vector<vector >::size() in current scope test6.C:45:

Is that expected[/quote]Yes, it is expected as you have not loaded the dictionary for the vector<vector >.

Cheers,
Philippe.

Hi,
Ok - after loading the dict I still see the error:

[code][lxplus305] cat loader.C
#include
#include
#ifdef MAKECINT
#pragma link C++ class vector<vector >+;
#pragma link C++ class vector<vector >+;
#endif
[lxplus305] root -b


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 5.22/00j 23 April 2010 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      http://root.cern.ch            *
    
  •                                     *
    

ROOT 5.22/00j (branches/v5-22-00-patches@33102, May 03 2010, 18:59:00 on linux)

CINT/ROOT C/C++ Interpreter version 5.16.29, Jan 08, 2008
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .L loader.C+
root [1] .L test6.C
root [2] t = new test6()
(class test6*)0xa1386b8
root [3] t.Loop()
Error: Can’t call vector<vector >::size() in current scope test6.C:45:
Possible candidates are…
(in vector<vector >)
Size: (class G__CINT_ENDL)164776952
*** Interpreter error recovered ***
root [4]
[/code]

test6.c and .h are attached. The root file can be found at d0.phys.washington.edu/~gwatts/test6.zip

Many thanks!
test6.h (3.4 KB)
test6.C (1.5 KB)

Hi,

I still can not reproduce it (even with root 5.22/00j on lxplus241).

What is the result of:root [] .L loader.C+ root [] .class vector<vector<float> >and then root [] .L loader.C++ root [] .class vector<vector<float> >

Cheers,
Philippe.