You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::u32string::erase编译报错,如何适配GCC使其正常运行?

GCC 9.4.0下std::u32string移除字符代码编译报错的解决

问题描述

我需要从std::u32string中移除指定字符,例如移除字符串U"abd|def"中的'|',编写的代码如下:

#include <string>

int main()
{
    std::u32string a = U"abd|def";
    a.erase(std::remove(a.begin(), a.end(), U'|'), a.end());
}

该代码在MacBook的Apple clang 14.0.0环境下可正常编译运行,但在Ubuntu系统的GCC 9.4.0编译时出现错误,错误信息为:

no instance of overloaded function "std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::erase [with _CharT=char32_t, _Traits=std::char_traits<char32_t>, _Alloc=std::allocator<char32_t>]" matches the argument listC/C++(304)

m.cpp(6, 7): argument types are: (int, __gnu_cxx::__normal_iterator<char32_t *, std::__cxx11::basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t>>>) 

m.cpp(6, 7): object type is: std::u32string

请问如何修改代码,使其在GCC环境下也能正常编译运行?

解决方法

问题根源是GCC 9.4.0对std::basic_string<char32_t>::erase的实现限制:旧版本GCC中,这个erase函数的重载不支持直接接收std::remove返回的迭代器作为第一个参数(编译器误将迭代器解析为整数类型的位置参数),但它支持传入两个迭代器构成的范围来删除元素。

可以通过以下两种方式修改:

方式一:显式处理迭代器范围(兼容C++11及以上)

先将std::remove的返回值保存为迭代器,再把这个迭代器和字符串末尾迭代器一起传给erase,同时必须显式包含<algorithm>头文件(std::remove的定义所在):

#include <string>
#include <algorithm>

int main()
{
    std::u32string a = U"abd|def";
    auto new_end = std::remove(a.begin(), a.end(), U'|');
    a.erase(new_end, a.end());
}

方式二:使用C++20的std::erase_if(需升级编译器)

如果可以将GCC版本升级到11及以上(支持C++20),可以使用更简洁的std::erase_if,无需手动处理迭代器:

#include <string>
#include <algorithm>

int main()
{
    std::u32string a = U"abd|def";
    std::erase_if(a, [](char32_t c) { return c == U'|'; });
}

内容的提问来源于stack exchange,提问作者Haohan Yang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:00:02