Confusion regarding accumulate with vectors

Hi there,

I’m pretty new to Root, so am not sure if I’m doing something wrong, but the following code is almost entirely copied from an example and runs fine on an online C++ Shell, however has an intermittent issue with the std::accumulate line when running in Root.

What is more confusing is that the same code worked when first tried in Root, and then having changed a copy of the code, closed and re-opened the terminal, it would not run?

The error that comes up is as follows: "Function accumulate(myvector.begin(),myvector.end(),0.0) is not defined in current scope ".

Any help would be appreciated.

Thanks,
Alistair.

{
#include <iostream>
#include <vector>
#include <numeric>

  std::vector<int> myvector;
  for (int i=1; i<=5; i++) myvector.push_back(i);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

int tot = std::accumulate(myvector.begin(),myvector.end(),0.0);

std::cout << tot << std::endl;

  return 0;
}```
___
_ROOT Version: 5.34/36
_Platform: Linux 2.6
_Compiler: Terminal
___

Hi Alistair,
I think the problem is that you have #includes inside the body of your function. More issues might be due to your ROOT version (please switch to v6 if possible, v5 has not been actively developed in years).

Cheers,
Enrico

Hi Enrico,

Thanks for the reply; I’ll try that, but I had a much longer function (not attached as it’s way too long) with the #includes outside and that still didn’t work?
I’ll try switching, but that may be difficult as I’m on a shared system - Any chance of a workaround for version 5?

Thanks again,
Alistair

Hi, as a start let’s see how it goes without includes in the function body :slight_smile:

1 Like

Sure; I tried that this morning first thing and it still didn’t like it; first of all I got the “Note: File “iostream” already loaded” warning, which stopped the macro, and when deleting this line, the first time the macro runs with no errors, but no output either, the second time it repeats the same note for “vector”, and then “numeric”.

When I comment out all of the “#includes” it then starts displaying the original “Function accumulate is not defined” error!

Thanks again for your help,
Alistair

This is the exact code I have in the macro; I realised I’d left “return 0;” in there from the original C++ example, but deleting this doesn’t change anything!

/*
#include <iostream>
#include <vector>
#include <numeric>
*/
{
  std::vector<int> myvector;
  for (int i=1; i<=5; i++) myvector.push_back(i);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

int tot = std::accumulate(myvector.begin(),myvector.end(),0.0);

std::cout << tot << std::endl;
}

Alistair

In case of an “unnamed macro”, the “{” MUST be the first character of this file (and NO “#include” inside).

In case of a “named macro”, usually all “#include” come first and then your own function begins.

2 Likes

Thanks, so as this is an unnamed macro I’m right to remove the #includes?

I think the easiest would be to give the macro a name and add #include <numeric> which contains std::accumulate

1 Like

Okay, I tried that and it still produces the same error?

#include <iostream>
#include <vector>
#include <numeric>
void testfunc(){
  std::vector<int> myvector;
  for (int i=1; i<=5; i++) myvector.push_back(i);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

int tot = std::accumulate(myvector.begin(),myvector.end(),0.0);

std::cout << tot << std::endl;
}

Alistair

this error?

(if yes that’s weird, function accumulate must be defined, you just included the relevant header :sweat_smile: is your compiler recent enough?)

1 Like

That’s the error, I’m running Scientific Linux 6.3 with GNOME 2.28.2. It’s a shared system and I’m just working out of the terminal - Is that the compiler information?
(Sorry, still very new to all of this!)

Let’s try to reduce this.
Save this code in macro.C and execute it with root -l -b -q macro.C. It should print 6.
I just tested it and it works with ROOT v6.14.
What do you get?

Code:

#include <numeric>
#include <vector>

void macro() {
   std::vector<int> v{1,2,3};
   int sum = std::accumulate(v.begin(), v.end(), 0);
   std::cout << sum << std::endl;
   return;
}

I understand that you can’t move away from ROOT v5, but please consider talking to your system administrator about it. v6 is actively being developed and has a better C++ interpreter (e.g. the macro above just works).

Cheers,
Enrico

P.S.
your compiler version is probably returned by gcc --version, unless you use clang in which it’s clang --version (it’s probably gcc :slight_smile: ).

1 Like

Alright, it’s saved, but as it’s a shared system I don’t have access to the original macro folder, so I use gROOT->SetMacroPath("[filepath]") every time I start Root. Is there a way I can execute it as you suggested while changing the file path?

Sorry to keep getting more awkward :stuck_out_tongue:

Thanks,
Alistair

And it’s GCC 4.4.6 by the way!

According to your first post here, you are using ROOT 5.34. In this case, you MUST precompile your named macro with ACLiC (if you need “std::accumulate”, of course), e.g.: root [0] .x testfunc.cxx++

2 Likes

In the “Welcome to ROOT” box, it says version 5.34/38, and I’ve tried compiling it using ACLiC, but it either throws a set of errors that don’t otherwise pop up in my code (although admittedly not using std::accumulate). I’ve also tried that, but it with my current macros, but it doesn’t run. Do I need to save it as a .cxx file, as opposed to .C?

No, you don’t need to rename your file.
You simply need to fix all warnings and errors reported by your compiler.

1 Like

I’ve tried executing the macro as a .cxx++ and it produced the error “macro accumulatetest.cxx not found in path [filepath]”, with the correct path, and also runs up to the known error with the std::accumulate when executed as .x accumulatetest.C, hence why I was asking about the extension change!

Thanks,
Alistair

root [0] .x accumulatetest.C++