首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >remove_if(str.begin(),str.end(),::isspace);::isspace意味着什么?

remove_if(str.begin(),str.end(),::isspace);::isspace意味着什么?
EN

Stack Overflow用户
提问于 2015-03-13 21:25:42
回答 3查看 863关注 0票数 3

我最近想通过使用STL找到一种修剪字符串的方法。我看到有人用

代码语言:javascript
复制
remove_if(str.begin(), str.end(), isspace);

我发现isspace是stl中的一个函数,标题是<ctype.h>。我把上面的代码和头文件放在我的函数中,然后它无法通过编译。编译器正在抱怨一些关于isspace的事情。

我试着

代码语言:javascript
复制
remove_if(str.begin(), str.end(), std::isspace);

它仍然无法通过编译。

然后我发现另一个男人用

代码语言:javascript
复制
remove_if(str.begin(), str.end(), ::isspace);

我试过这个,它可以通过编译。

我的问题是

  1. 为什么我不能通过使用前两种方式传递编译。
  2. ::isspace是什么意思?它想说它是属于STL还是其他什么的?我对::的用法感到困惑
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-13 21:46:33

std::isspace是C++中的重载函数,模板函数在<locale>中声明。实现允许静默地包含您不需要的附加标头,而且许多实现都是这样做的。他们这样做是因为他们在内部使用这些额外的头。

通常,传递给std::isspace的参数将决定选择哪种重载,但在您的情况下,您不是传递任何参数,而是试图确定它的地址。

::isspace可以工作,因为它不是重载的函数。

就像是

代码语言:javascript
复制
template <typename T>
void f(T) { }

void g(int) { }
void h() { f(g); } // okay, g is not an overloaded function

void i(int) { }
void i(char) { }
void j() { f(i); } // error, the compiler cannot know whether you want the void(int)
                   // function, or the void(char) one

注释中告诉您的内容是正确的,确保它工作的简单方法是根本不传递isspace的地址,而是创建一个调用isspace的函数。无论如何,出于其他原因,您都需要这样做,但它也很好地完全避免了这个问题。

票数 5
EN

Stack Overflow用户

发布于 2015-03-13 21:47:05

::isspace意味着您要显式调用全局方法isspace。C标准库方法都是全局的,<ctype.h>是C标准库头。

C中不存在名称空间,所以在使用C库标题时,不使用std命名空间。与使用std命名空间的C++对应的<ctype.h><cctype>

当您试图处理名称冲突时,前面的::表示法非常有用。例如,你可以有这样的代码.

代码语言:javascript
复制
void DoSomething(void);

class Foo {
  void DoSomething (void); // Uhoh, this method shadows the global DoSomething.
  void DoSomethingElse(void) {
    Foo::DoSomething(); // Calls the class local DoSomething()
    ::DoSomething(); // Calls the global DoSomething()
  }
};
票数 3
EN

Stack Overflow用户

发布于 2017-04-28 07:24:17

注意,在C++中有两个版本的std::ispace函数,即两个重载。其中第一个在<cctype> C兼容性标头中定义为

代码语言:javascript
复制
#include <ctype.h>
namespace std { using isspace = ::isspace; }

其中,<ctype.h>是相应的C标头,应该将isspace (在全局命名空间中,即::isspace)定义为:

代码语言:javascript
复制
int isspace(int);

第二个重载在<locale>中定义为:

代码语言:javascript
复制
namespace std {
  template<class charT> bool isspace(charT, const locale &);
}

如果由于某种原因(直接或间接地)同时包含<cctype><locale>,则std::isspace将得到两个重写,但会得到一个全局::isspace函数。因此,直接使用::isspace可以很好的工作,但是使用std::isspace会出错,因为编译器无法解决使用哪种过载的模糊性。

要解决这个问题,您可以告诉编译器,通过将函数转换为所需的类型,意味着哪种重载,例如:

代码语言:javascript
复制
std::remove_if(str.begin(),
               str.end(),
               static_cast<int(&)(int)>(std::isspace)); // reference to function
    // Or even static_cast<int(*)(int)>(std::isspace)); // pointer to function

PS:文字::被称为作用域解析运算符,所以在A::b的情况下,它指的是当前上下文中可访问的名称空间A中的b。当::前面没有名称时,它引用全局命名空间。有关详细信息,请参阅最新的[expr.prim.id.qual]标准草案中的C++。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29042224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档