gpt4 book ai didi

c++ - 将 std::ispunct 作为参数传递给 remove_copy_if() 无法编译

转载 作者:行者123 更新时间:2023-11-27 23:37:01 26 4
gpt4 key购买 nike

我试图将 std::ispunct 作为最后一个参数传递给 remove_copy_if,但发现编译失败。但是,如果我传递 ispunct(只是删除了 std::),程序会按预期编译和运行。

代码:

#include<iostream>
#include<map>
#include<cctype>
#include<algorithm>
#include<iterator>

using std::map;
using std::string;

string strip_punct(const string &s) {
string target;
remove_copy_if(s.begin(), s.end(), std::back_inserter(target), std::ispunct);
return target;
}

int main() {
string word = "abc.";
string target = strip_punct(word);
std::cout << "target: " << target << "\n";
return 0;
}

错误信息:

$ g++ --std=c++11 -o problem_11_4.out problem_11_4.cpp
problem_11_4.cpp: In function 'std::string strip_punct(const string&)':
problem_11_4.cpp:12:80: error: no matching function for call to 'remove_copy_if(std::__cxx11::basic_string<char>::const_iterator, std::__cxx11::basic_string<char>::const_iterator, std::back_insert_iterator<std::__cxx11::basic_string<char> >, <unresolved overloaded function type>)'
12 | remove_copy_if(s.begin(), s.end(), std::back_inserter(target), std::ispunct);
| ^
In file included from /usr/local/Cellar/gcc/9.2.0_1/include/c++/9.2.0/algorithm:62,
from problem_11_4.cpp:4:
/usr/local/Cellar/gcc/9.2.0_1/include/c++/9.2.0/bits/stl_algo.h:703:5: note: candidate: 'template<class _IIter, class _OIter, class _Predicate> _OIter std::remove_copy_if(_IIter, _IIter, _OIter, _Predicate)'
703 | remove_copy_if(_InputIterator __first, _InputIterator __last,
| ^~~~~~~~~~~~~~
/usr/local/Cellar/gcc/9.2.0_1/include/c++/9.2.0/bits/stl_algo.h:703:5: note: template argument deduction/substitution failed:
problem_11_4.cpp:12:80: note: couldn't deduce template parameter '_Predicate'
12 | remove_copy_if(s.begin(), s.end(), std::back_inserter(target), std::ispunct);
| ^

我在 SO 上搜索并发现了这个问题:Why std:: is not needed when using ispunct() in C++?这很有帮助,现在我知道 ispunct 可以在没有 std:: 的情况下使用。但是,我编写了另一个程序并发现 ispunctstd::ispunct 单独使用(不作为参数)时都能很好地工作。我仍然不明白为什么在将 ispunct 用作参数时不允许使用 std::

最佳答案

std::ispunct是一个重载函数。 <cctype> 中存在一个版本和 <locale> 中的一个版本.即使您不包括 <locale> ,您的其中一个包含会带来重载并导致推导失败,因为重载函数无法推导类型。

解决这个问题的方法是包装 std::ispunct在 lambda 中,因为在 lambda 的主体中,编译器可以执行重载解析并调用正确的函数。那会给你

remove_copy_if(s.begin(), 
s.end(),
std::back_inserter(target),
[](unsigned char ch){ return std::ispunct(ch); }); // use unsigned char here to stop any possible UB

关于c++ - 将 std::ispunct 作为参数传递给 remove_copy_if() 无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58527598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com