Template error in TTreeReaderArray type


When I use

TTreeReaderArray<float> amplTrMCP_q1(reader, q1);

(q1 is the string with branch name and reader holds the tree.)

And store this in an Array

amplitude_MCP->AddLast((TTreeReaderArray) amplTrMCP_q1);

It gives the following error.

error: use of class template ‘TTreeReaderArray’ requires template arguments
amplitude_MCP->AddLast((TTreeReaderArray) amplTrMCP_q1);
note: template is declared here
TTreeReaderArray final : public ROOT::Internal::TTreeReaderArrayBase {

I don’t know, what does it mean?


you say to the compiler that you want to convert to TTreeReaderArray, but you have to also specify which type should be stored inside the array. So, the complete type name would be TTreeReaderArray<float> as in your first line of code.

Thanks for this suggesion.
When I set this

amplitude_MCP->AddLast((TTreeReaderArray<float>) amplTrMCP_q1);

I get the following error -

error: C-style cast from ‘TTreeReaderArray<float>’ to ‘TTreeReaderArray<float>’ uses
deleted function
amplitude_MCP->AddLast((TTreeReaderArray<float>) amplTrMCP_q1);
note: candidate constructor (the implicit copy constructor) has been implicitly deleted
TTreeReaderArray final : public ROOT::Internal::TTreeReaderArrayBase {

the issue is that this expression up here is not valid C++. The error is saying that TTreeReaderArray is not a valid type, because it’s a class template, i.e. TTreeReaderArray<float> or TTreeReaderArray<int> are valid types, but just TTreeReaderArray is not.

But even then, AddLast doesn’t take a TTreeReaderArray as argument, but a TObject*, and TTreeReaderArray is not convertible to TObject, so you can’t put TTreeReaderArray's in TArrays.

A container that you can fill with TTreeReaderArrays is, for example, a std::vector<TTreeReaderArrayBase*>.

Hope this helps!

Thanks Enrico!
when I use it,

amplitude_MCP->AddLast((std::vector<TTreeReaderArrayBase*>) amplTrMCP_q1);

I find the following error.

from the docs, it seems that TTreeReaderArrayBase is an internal class (it’s in ROOT::Internal), so you could use ROOT::Internal::TTreeReaderArrayBase instead of just TTreeReaderArrayBase, but since it’s an internal class, ROOT might change it in future versions without notice.

However, you cannot convert amplTrMCP_q1 to a std::vector<TTreeReaderArrayBase*>, that’s not its type nor a type it inherits from. And you cannot pass a std::vector to AddLast, as that method accepts a TObject*. My suggestion was to do something more similar to:

std::vector<TTreeReaderArray<float>> readerarrays; // or TTreeReaderArrayBase*
readerarrays.push_back(amplTrMCP_q1); // or &amplTrMCP_q1

where amplTrMCP_q1 would still be a TTreeReaderArray<float>.


C++ is a strongly typed language, so it’s often important to know exactly what type your objects are, how different types relate to one another, and what types the functions you are calling expect (and you have to match them exactly). The ROOT reference guide provides that information for all public ROOT types.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.