【发布时间】:2021-11-20 07:00:56
【问题描述】:
假设我想使用erase-remove 习惯用法删除std::string 中的所有标点符号。
但是,让str 为std::string 类型,此调用将无法编译
str.erase( std::remove_if(str.begin(), str.end(), std::ispunct), str.end() );
现在我猜,严格来说std::ispunct 可调用参数类型是int,因此与范围元素类型char 不匹配。
但是,由于char 是数字类型,它应该可以转换为int。我正在使用 Lippman 的 C++ Primer 书,其中指出
采用谓词的算法在输入范围内的元素上调用谓词。 [...] 必须可以将元素类型转换为输入范围内的参数类型。
上面的声明中给出了哪个imo。
同样std::ispunct 返回一个int,因此应该可以用作条件。
那么为什么编译器会抱怨no matching function for call to 'remove_if'?
(clang++ -std=c++11 -o main main.cc)
解决方法是使用 lambda
str.erase( std::remove_if(str.begin(), str.end(),
[] ( char ch ) { return std::ispunct(ch); }),
str.end() );
仍然让我感到惊讶的是 lambda 是必要的......
提前致谢!
【问题讨论】:
-
参见 Notes 这里 - en.cppreference.com/w/cpp/string/byte/ispunct - 基本上它是不安全的,而 lambda 是首选的安全选项。
标签: c++ stl implicit-conversion