File refuses to compile std::erase() even if using -std=g++23

37 Views Asked by At

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;
}
0

There are 0 best solutions below