I'm having a huge problem. I have a struct
struct Particle {
int x = -1;
int y = -1;
int type = -1;
int number = -1;
bool operator==(Particle p) {
if (this->x == p.x && this->y == p.y && this->type == p.type
&& this->number == p.number) { return true; }
else { return false; }
}
};
and an array of vectors of them std::vector<Particle> energies[5]; on which I call the method std::erase(energies[neighbor.type], neighbor);
The problem I have is that compiling using g++ crystal.cpp -std=c++23 -o crystal $(root-config --cflags --glibs) (the latter part is for the CERN ROOT library which I need in my program) gives me the compiler error
$: g++ crystal.cpp -std=c++23 -o crystal `root-config --cflags --glibs`
crystal.cpp: In lambda function:
crystal.cpp:94:22: error: ‘erase’ is not a member of ‘std’
std::erase(energies[neighbor.type], neighbor);
and I have no clue why that is.
Running g++ --version says I have 13.2.1 and that function should have been added in version 9 according to this table https://en.cppreference.com/w/Template:cpp/compiler_support/20. The error I get is the same if I substitute g++ with clang++.
Running the mock code
#include <vector>
#include <iostream>
struct Particle {
int x = -1;
int y = -1;
bool operator==(Particle p) {
if (this->x == p.x && this->y == p.y) { return true; }
else { return false; }
}
};
int main() {
std::vector<Particle> v = {{1, 0}, {0, 1}, {1, 1}};
Particle to_erase = {1, 0};
std::erase(v, to_erase);
for (auto &entry : v) {
std::cout << entry.x << ' ' << entry.y << std::endl;
}
std::cout << std::endl;
}
in an online compiler https://www.onlinegdb.com/ compiles and works as expected. I have absolutely no idea why this case of "doesn't work on my machine" has struck me, but I couldn't find any issues akin to mine online. Please help, I'm desperate.
EDIT: adding minimal non-working example
#include <fstream>
#include <iostream>
#include <functional>
#include "TApplication.h"
#include "TRandom3.h"
#include "TGraph.h"
#include "TSystem.h"
#include "TPad.h"
#include "TCanvas.h"
//#include <unistd.h>
#include <vector>
#include <stdio.h>
struct Particle {
int x = -1;
int y = -1;
int type = -1;
int number = -1;
bool operator==(Particle const&) const = default;
};
int main() {
TApplication app("app", 0, 0);
TRandom3 rng;
rng.SetSeed(12345);
int mat_size = 50;
int max_particles = 10;
Particle empty_site = {-1, -1, -1, -1};
std::vector<std::vector<Particle>> positions;
for (auto &vector : positions) {
std::fill(std::begin(vector), std::end(vector), empty_site);
}
std::vector<Particle> energies[5];
// manual memory allocation
for (auto &vector : energies) {
vector.reserve(max_particles);
}
// Periodic Boundary Conditions
auto Index = [&mat_size](int i) -> int {
return ((i % mat_size) + mat_size) % mat_size;
};
auto MoveIn = [&positions, &energies, &Index, &empty_site] (int x, int y, int number) -> void {
Particle neighbors[4] = {positions[Index(y+1)][x], positions[y][Index(x-1)], positions[Index(y-1)][x], positions[y][Index(x+1)]};
int num_neighbors = 0;
for (auto &neighbor : neighbors) {
if (neighbor.type != empty_site.type) {
// calculate number of neighbors for that site
num_neighbors++;
// update neighbor at energy with new energy
std::erase(energies[neighbor.type], neighbor);
neighbor.type++;
energies[neighbor.type].push_back(neighbor);
// update neighbor at position with new energy
positions.at(neighbor.y).at(neighbor.x) = neighbor;
}
}
// insert particle in site
Particle deposited = {x, y, num_neighbors, number};
// update positions and energies with the corrected particles
positions.at(y).at(x) = deposited;
energies[deposited.type].push_back(deposited);
};
app.Run(true);
return 0;
}