Почему в C++20 нет функции std::erase. G++ MSYS2 Windows

Очевидно, std::erase был добавлен в C++20, но мой компилятор почему-то не позволяет мне его использовать.

код

#include <iostream>
#include <vector>
#include <string>
#include <string.h>
using namespace std;

int main() {
    int num1, num2 = 0;
    cin >> num1;
    cin >> num2;
    int sum = num1 + num2;

    vector<char> vec_num1(to_string(num1).begin(), to_string(num1).end());
    vector<char> vec_num2(to_string(num2).begin(), to_string(num2).end());

    std::erase(vec_num1, "0");
    std::erase(vec_num2, "0");

    int removezero1, removezero2, removezerosum = 0;

    for (int v : vec_num1) {
        removezero1 = removezero1 * 10 + v;
    }
    for (int v : vec_num1) {
        removezero2 = removezero2 * 10 + v;
    }
    for (int v : vec_num1) {
        removezerosum = removezerosum * 10 + v;
    }

    if (removezero1 + removezero2 == removezerosum)
    {
        cout << "YES";
    }
    else {
        cout << "NO";
    }


}

ошибка

main.cpp: 16:10: ошибка: «стирание» не является членом «стандартного стандарта» 16 | std::erase(vec_num1, "0"); | ^~~~~ main.cpp: 17:10: ошибка: «стирание» не является членом «стандартного стандарта» 17 | std::erase(vec_num2, "0"); | ^~~~~

gcc версии 12.2.0

Я не проверял, но вполне возможно, что gcc просто еще не реализовал эту конкретную функцию. Иногда требуются годы, чтобы новый стандарт C++ был полностью реализован в gcc.

Sam Varshavchik 21.02.2023 14:00

Это разочаровывает. Казалось бы, такая приятная функция. Теперь придется пройти долгий путь.

Who Cares 21.02.2023 14:07

Вы имеете в виду std::erase, а не std::erased (которого вообще не существует)

Fareanor 21.02.2023 14:07

Да, я имею в виду std::erase. это код, который я написал

Who Cares 21.02.2023 14:08

Да, но зачем тогда добавлять букву «д» в заголовок и в вопрос?

Fareanor 21.02.2023 14:08

Похоже, вы забыли добавить -std=c++20 в командную строку. Также у вас есть std::vector<char>, но вы пытаетесь стереть строку. Должно быть std::erase(vec_num1, '0');. См. рабочий пример: godbolt.org/z/qxqKocc69

sklott 21.02.2023 14:09

Реализовано в gcc 9 согласно en.cppreference.com/w/cpp/compiler_support

Alan Birtles 21.02.2023 14:09

Кроме того, vector<char> vec_num1(to_string(num1).begin(), to_string(num1).end()); — неверный код. Вы не можете этого сделать. Вам нужно что-то сделать: string tmp = to_string(num1); vector<char> vec_num1(tmp.begin(), tmp.end());

sklott 21.02.2023 14:11

какие флаги тебе передать компилятору?

463035818_is_not_a_number 21.02.2023 14:13

-std=gnu++20 передать этот флаг.

Who Cares 21.02.2023 14:19

Большое спасибо. Код работает!

Who Cares 21.02.2023 14:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
11
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Документация GCC 12.2 по стандартным параметрам языка:

По умолчанию, если параметры диалекта языка C++ не заданы, используется значение -std=gnu++17.

Итак, чтобы использовать функции C++20, вам нужно указать -std=c++20 или -std=gnu++20.

Теперь я получаю еще одну очень длинную ошибку. Слишком долго, чтобы добавить комментарий.

Who Cares 21.02.2023 14:17

@WhoCares Другая проблема, не связанная с языковой версией. Возможно, напишите как новый вопрос после того, как вы применили все полезные советы из комментариев и компилятора. ;-) Кроме того, пожалуйста, не пытайтесь кодировать C++ методом проб и ошибок. Есть несколько языков, менее терпимых к такому подходу. :-)

DevSolar 21.02.2023 14:54

@WhoCares А почему ты игнорируешь мой ответ? Мой ответ - лучший ответ. :)

Vlad from Moscow 21.02.2023 15:29

@VladfromMoscow Действительно так, но я не могу удалить свой, пока он принят. ;-)

DevSolar 21.02.2023 16:26

@DevSolar В следующий раз не торопись. :)

Vlad from Moscow 21.02.2023 17:13

Как следует из сообщения об ошибке

main.cpp:16:10: ошибка: 'erase' не является членом 'std' 16 | std::erase(vec_num1, "0"); | ^~~~~ main.cpp:17:10: ошибка: «стереть» не является членом 'std' 17 | std::erase(vec_num2, "0"); | ^~~~~

вы компилируете программу компилятором, использующим возможности C++17.

Вам нужно указать компилятору использовать функции C++ 20, например -std=c++20.

Но в любом случае ваш код неверен, потому что, по крайней мере, в этих объявлениях

vector<char> vec_num1(to_string(num1).begin(), to_string(num1).end());
vector<char> vec_num2(to_string(num2).begin(), to_string(num2).end());
                      ^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^

используются итераторы различных последовательностей временно создаваемых объектов. То есть используются недопустимые диапазоны.

Вам нужно создать промежуточные строковые объекты, например

auto s1 = std::to_string( num1 );
vector<char> vec_num1(s1.begin(), s1.end());
auto s2 = std::to_string( num2 );
vector<char> vec_num2(s2.begin(), s2.end());

И вызовы функции std::erase тоже ошибочны. Например, вместо

std::erase(vec_num1, "0");
std::erase(vec_num2, "0");

вам нужно написать

std::erase(vec_num1, '0');
std::erase(vec_num2, '0');

То есть вместо строковых литералов вы должны использовать символьные литералы, потому что тип значения векторов — char.

Также в этой декларации

int removezero1, removezero2, removezerosum = 0;

там инициализируется нулем только последний декларатор removezerosum. Вам нужно написать

int removezero1 = 0, removezero2 = 0, removezerosum = 0;

Также заголовок

#include <string.h>

является избыточным. Убери это.

Другие вопросы по теме