Problem using std::find_if with TCollection

Hello

Does TCollection fully support (in git master, v6.05/02) STL algorithms?
If so, what am I doing wrong?

The following works fine:

[code]#include “TNamed.h”
#include “TList.h”
#include
#include

void Print(TObject* a) { std::cout << a->GetName() << std::endl; }

int main()
{
TList z;
z.Add(new TNamed(“a”,“a”));
z.Add(new TNamed(“b”,“b”));
z.Add(new TNamed(“c”,“c”));

std::for_each( z.begin(), z.end(), Print );
for(auto p : z) { p->ls(); }
}
[/code]

Compile & execute:

ganp115:~/work/ROOT% g++ `root-config --cflags --ldflags` tlist_iterator.cxx `root-config --libs` ganp115:~/work/ROOT% ./a.out a b c OBJ: TNamed a a : 0 at: 0x11383a0 OBJ: TNamed b b : 0 at: 0x1138420 OBJ: TNamed c c : 0 at: 0x11384a0

I can (obviously) use std::find_if with a std::vector<TObject*>:

[code]#include “TNamed.h”
#include “TString.h”
#include
#include
#include

struct FindObject {
TString d;
FindObject(const TString& p) : d§ {}
bool operator()(TObject *a)
{
if(!strcmp(d.Data(),a->GetName())) return true;
return false;
}
};

int main()
{
std::vector<TObject*> vobj;
vobj.push_back(new TNamed(“a”,“a”));
vobj.push_back(new TNamed(“b”,“b”));
vobj.push_back(new TNamed(“c”,“c”));
auto obj = std::find_if( vobj.begin(), vobj.end(), FindObject(“b”) );
if(*obj) (*obj)->ls();
}[/code]

which gives:

ganp115:~/work/ROOT% g++ `root-config --cflags --ldflags` tlist_iterator2.cxx `root-config --libs` ganp115:~/work/ROOT% ./a.out OBJ: TNamed b b : 0 at: 0x1470410

but if I try to replace the vector with a TList using the same functor object:

[code]int main()
{
TList z;
z.Add(new TNamed(“a”,“a”));
z.Add(new TNamed(“b”,“b”));
z.Add(new TNamed(“c”,“c”));

auto obj = std::find_if( z.begin(), z.end(), FindObject(“b”) );
if(*obj) (*obj)->ls();
}
[/code]

I get the following compilation errors:

ganp115:~/work/ROOT% g++ `root-config --cflags --ldflags` tlist_iterator3.cxx `root-config --libs` In file included from /usr/include/c++/4.9/algorithm:62:0, from /home/john/software/build/root-trunk/include/RWrap_libcpp_string_view.h:37, from /home/john/software/build/root-trunk/include/RStringView.h:26, from /home/john/software/build/root-trunk/include/TString.h:41, from /home/john/software/build/root-trunk/include/TNamed.h:29, from tlist_iterator3.cxx:1: /usr/include/c++/4.9/bits/stl_algo.h: In instantiation of ‘_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = TIter; _Predicate = __gnu_cxx::__ops::_Iter_pred<FindObject>]’: /usr/include/c++/4.9/bits/stl_algo.h:3805:45: required from ‘_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = TIter; _Predicate = FindObject]’ tlist_iterator3.cxx:24:65: required from here /usr/include/c++/4.9/bits/stl_algo.h:162:42: error: no matching function for call to ‘__iterator_category(TIter&)’ std::__iterator_category(__first)); ^ /usr/include/c++/4.9/bits/stl_algo.h:162:42: note: candidate is: In file included from /usr/include/c++/4.9/bits/stl_algobase.h:65:0, from /usr/include/c++/4.9/vector:60, from /home/john/software/build/root-trunk/include/TGenericClassInfo.h:15, from /home/john/software/build/root-trunk/include/Rtypes.h:230, from /home/john/software/build/root-trunk/include/TObject.h:31, from /home/john/software/build/root-trunk/include/TNamed.h:26, from tlist_iterator3.cxx:1: /usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: note: template<class _Iter> typename std::iterator_traits<_Iterator>::iterator_category std::__iterator_category(const _Iter&) __iterator_category(const _Iter&) ^ /usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: note: template argument deduction/substitution failed: /usr/include/c++/4.9/bits/stl_iterator_base_types.h: In substitution of ‘template<class _Iter> typename std::iterator_traits<_Iterator>::iterator_category std::__iterator_category(const _Iter&) [with _Iter = TIter]’: /usr/include/c++/4.9/bits/stl_algo.h:162:42: required from ‘_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = TIter; _Predicate = __gnu_cxx::__ops::_Iter_pred<FindObject>]’ /usr/include/c++/4.9/bits/stl_algo.h:3805:45: required from ‘_IIter std::find_if(_IIter, _IIter, _Predicate) [with _IIter = TIter; _Predicate = FindObject]’ tlist_iterator3.cxx:24:65: required from here /usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<TIter>’

Is it me?
Cheers

Hello,

I could use it this way:

TIterCategory<TList> iter(&z);
auto obj = std::find_if( iter.Begin(), iter.End(), FindObject("b") );

I’ll get a more definitive answer for you about the state of TCollection and STL algorithms support; we’ll followup here when there is more information for you.

Yours,
David

Hi David,
yes, that works!
It looks like things are still quite experimental, because there is nothing on
using STL algorithms with TCollections in the User’s Guide, and the only clue
I had was from the class description of TList where an example of use
of the std::for_each is given.
I look forward to hearing from you.
Thanks a lot
John