TListAndSTL

This is an example of using TList with STL algoritms in CLING.

Output produced by .x TListAndSTL.C

TListAndSTL.C code

Author: Anar Manafov
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Wednesday, August 10, 2022 at 09:47 AM.

In [1]:
%%cpp -d

STD

In [2]:
%%cpp -d
#include <algorithm>
#include <iostream>
#include <sstream>

ROOT

In [3]:
%%cpp -d
#include "TList.h"
#include "TCollection.h"
#include "TObjString.h"

A functor for the for_each algorithm

In [4]:
struct SEnumFunctor {
   bool operator()(TObject *aObj) {
      if (!aObj)
         return false;

      TObjString *str(dynamic_cast<TObjString*>(aObj));
      if (!str)
         return false;

      cout << "Value: " << str->String().Data() << endl;
      return true;
   }
};
%%cpp -d
input_line_44:15:2: error: expected expression
 %%cpp -d
 ^
input_line_44:15:3: error: expected expression
 %%cpp -d
  ^
input_line_44:15:4: error: use of undeclared identifier 'cpp'
 %%cpp -d
   ^
input_line_44:15:9: error: use of undeclared identifier 'd'
 %%cpp -d
        ^

A functor for the find_if algorithm

In [5]:
struct SFind {
   // using this ugly constructor, since there is problems with std::bindX in CINT

   SFind(const TString &aStr): fToFind(aStr) {

   }
   bool operator()(TObject *aObj) {
      TObjString *str(dynamic_cast<TObjString*>(aObj));
      return !str->String().CompareTo(fToFind);
   }
private:
   const TString fToFind;
};
In [6]:
const Int_t size(10);
input_line_55:2:2: warning: 'size' shadows a declaration with the same name in the 'std' namespace; use '::size' to reference this declaration
 const Int_t size(10);
 ^

Initializing TList container

In [7]:
TList stringList;
ostringstream ss;
for (int i = 0; i < size; ++i) {
   ss << "test string #" << i;
   TObjString *s(new TObjString(ss.str().c_str()));
   stringList.Add(s);
   ss.str("");
}
input_line_56:4:21: error: reference to 'size' is ambiguous
for (int i = 0; i < size; ++i) {
                    ^
input_line_55:2:14: note: candidate found by name lookup is '__cling_N523::size'
 const Int_t size(10);
             ^
/usr/include/c++/9/bits/range_access.h:252:5: note: candidate found by name lookup is 'std::size'
    size(const _Tp (&/*__array*/)[_Nm]) noexcept
    ^
/usr/include/c++/9/bits/range_access.h:242:5: note: candidate found by name lookup is 'std::size'
    size(const _Container& __cont) noexcept(noexcept(__cont.size()))
    ^
input_line_56:4:21: error: reference to 'size' is ambiguous
for (int i = 0; i < size; ++i) {
                    ^
input_line_55:2:14: note: candidate found by name lookup is '__cling_N523::size'
 const Int_t size(10);
             ^
/usr/include/c++/9/bits/range_access.h:252:5: note: candidate found by name lookup is 'std::size'
    size(const _Tp (&/*__array*/)[_Nm]) noexcept
    ^
/usr/include/c++/9/bits/range_access.h:242:5: note: candidate found by name lookup is 'std::size'
    size(const _Container& __cont) noexcept(noexcept(__cont.size()))
    ^

Example #1

Running the std::for_each algorithm on the list

In [8]:
for_each(stringList.begin(), stringList.end(), SEnumFunctor());
input_line_58:2:12: error: use of undeclared identifier 'stringList'
 (for_each(stringList.begin(), stringList.end(), SEnumFunctor()))
           ^
input_line_58:2:32: error: use of undeclared identifier 'stringList'
 (for_each(stringList.begin(), stringList.end(), SEnumFunctor()))
                               ^
input_line_58:2:50: error: use of undeclared identifier 'SEnumFunctor'
 (for_each(stringList.begin(), stringList.end(), SEnumFunctor()))
                                                 ^
Error in <HandleInterpreterException>: Error evaluating expression (for_each(stringList.begin(), stringList.end(), SEnumFunctor()))
Execution of your code was aborted.

Example #2

We can try to find something in the container using the std::find_if algorithm on the list

In [9]:
string strToFind("test string #4");
SFind func(strToFind.c_str());

TIterCategory<TList> iter_cat(&stringList);
TIterCategory<TList> found
   = find_if(iter_cat.Begin(), TIterCategory<TList>::End(), func);
IncrementalExecutor::executeFunction: symbol '_ZN5cling7runtime8internal15LifetimeHandlerD1Ev' unresolved while linking function '_GLOBAL__sub_I_cling_module_284'!
You are probably missing the definition of cling::runtime::internal::LifetimeHandler::~LifetimeHandler()
Maybe you need to load the corresponding shared library?
IncrementalExecutor::executeFunction: symbol '_ZN5cling7runtime8internal15LifetimeHandlerC1EPNS1_15DynamicExprInfoEPN5clang11DeclContextEPKcPNS_11InterpreterE' unresolved while linking function '_GLOBAL__sub_I_cling_module_284'!
You are probably missing the definition of cling::runtime::internal::LifetimeHandler::LifetimeHandler(cling::runtime::internal::DynamicExprInfo*, clang::DeclContext*, char const*, cling::Interpreter*)
Maybe you need to load the corresponding shared library?

Checking the result

In [10]:
if (!(*found)) {
   cerr << "Can't find the string: \"" << strToFind << "\" in the container" << endl;
   return;
}

TObjString *str(dynamic_cast<TObjString*>(*found));
if (!str) {
   cerr << "Can't find the string: \"" << strToFind << "\" in the container" << endl;
   return;
}

cout << "The string has been found: " << str->String().Data() << endl;
Can't find the string: "" in the container
Can't find the string: "" in the container