首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当与smatch::str一起使用时,为什么mem_fn无法编译?

在C++中,mem_fn是一个函数模板,用于创建成员函数指针的包装器。它可以将成员函数转换为可调用对象,以便在不同的上下文中使用。

然而,当与smatch::str一起使用时,可能会导致mem_fn无法编译的问题。smatch是C++标准库中的一个类,用于存储正则表达式匹配的结果。它具有一个名为str的成员函数,用于返回匹配的字符串。

问题出现的原因是,smatch::str是一个成员函数,而不是一个成员函数指针。而mem_fn期望一个成员函数指针作为参数,因此无法直接使用smatch::str。

解决这个问题的方法是使用bind函数,将成员函数绑定到对象上。bind函数可以将成员函数转换为可调用对象,类似于mem_fn的功能。以下是一个示例代码:

代码语言:txt
复制
#include <iostream>
#include <functional>
#include <regex>

int main() {
    std::string input = "Hello World";
    std::regex pattern("Hello");

    std::smatch match;
    std::regex_search(input, match, pattern);

    auto str_fn = std::bind(&std::smatch::str, &match);
    std::cout << str_fn() << std::endl;

    return 0;
}

在上述代码中,我们使用bind函数将smatch::str绑定到match对象上,并将结果存储在str_fn中。然后,我们可以通过调用str_fn来获取匹配的字符串。

需要注意的是,bind函数需要指定成员函数的地址,并且需要传递对象的指针作为第一个参数。在上述示例中,我们使用&match获取match对象的指针。

总结起来,当与smatch::str一起使用时,mem_fn无法编译的原因是因为smatch::str是一个成员函数而不是成员函数指针。解决这个问题的方法是使用bind函数将成员函数绑定到对象上。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++11常用新特性快速一览

C++ 不允许直接将 void * 隐式转换到其他类型,但如果 NULL 被定义为 ((void*)0),那么编译 char *ch = NULL 时,NULL 只好被定义为 0。...需要使用 NULL 时候,养成直接使用 nullptr 的习惯。 2. 类型推导 C++11 引入了 auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。...模板增强 外部模板 传统 C++ 中,模板只有在使用时才会被编译器实例化。只要在每个编译单元(文件)中编译的代码中遇到了被完整定义的模板,都会实例化。这就产生了重复实例化而导致的编译时间的增加。...注意值捕获的前提是变量可以拷贝,且被捕获的变量在 lambda 表达式被创建时拷贝,而非调用时才拷贝。如果希望 lambda 表达式在调用时能即时访问外部变量,我们应当使用引用方式捕获。...value) {return value % this->divisor == 0; }; } 尽管还是以值方式捕获,但是捕获的是指针,其实相当于以引用的方式捕获了当前类对象,所以 lambda 表达式的闭包一个类对象绑定在一起

2.6K50
  • C++:33---类成员指针

    如果没有这对括号,编译器将认为该声明是一个(无效的)函数声明: 错误的原因:编译器会认为p是一个普通函数,并且返回Screen类的一个char成员。...*->*的运算多想。然而pmfpmf2并不是一个函数,因此代码错误 char c1 = myScreen.*pmf(); //错误的//其等价于myScreen....因此在find_if的源码内部执行如下形式的代码,从而导致无法通过编译: //检查对当前元素的断言是否为真if(fp(*it)) //错误,想要通过成员指针调用函数,必须使用->*运算符 显然该语句试图调用的是传入的对象...我们也可以采取另一种方法,就是使用标准库功能mem_fn来让编译器负责推断成员的类型 mem_fn也定义在functional头文件中,并且可以从成员指针生成一个可调用对象 和function不同的是:...mem_fn可以根据成员指针的类型推断可调用对象的类型,而无须用户显式地指定 例如:我们使用mem_fn生成一个可调用对象,该对象接受一个string实参,返回一个bool值(编译器自动推断的) std

    89030

    c++11线程池的实现原理及回调函数的使用

    有新的任务进来,从线程池中取出一个空闲的线程处理任务然后任务处理完成之后,该线程被重新放回到线程池中,供其他的任务使用。...线程池中的线程都在处理任务时,就没有空闲线程供使用,此时,若有新的任务产生,只能等待线程池中有线程结束任务空闲才能执行。 线程池优点 线程本来就是可重用的资源,不需要每次使用时都进行初始化。...还比如把计算任务都放在主线程进行,那么势必会阻塞主线程的处理流程,无法做到实时处理。使用多线程技术是大家自然而然想到的方案。..."<< str.c_str() <<" " << (int)c <<" " << std::this_thread::get_id() << std::endl; return str;...: .commit(std::mem_fn(&Dog::sayHello), this) template<class F, class...

    1.3K20

    C++可调用Callable类型的总结

    因为函数对象一般用于模板参数, 模板一般会在编译时会做一些优化. 因此函数对象一般快于普通函数. 类也可以在使用的时候动态再产生, 节省成本....这里不提及模板函数, 因为模板函数的概念只存在于编译期, 运行期的函数没有模板的概念, 都是经过完全特化过的, 因此普通函数/类成员函数的概念是一致的....= "string"]{ return str; }(); // 此时z是const char* 类型,存储字符串 string //不能复制只能移动的对象,可以用std::move初始化变量 auto...cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n'; ++n1; ++n2; // ++n3; //无法编译... std::bind 相比, std::mem_fn 的范围又要小一些, 仅调用成员函数, 并且可以省略掉用于调用对象的占位符.

    26920

    【笔记】《C++Primer》—— 第17章:标准库特殊设施

    这里要注意string的下标编号习惯bieset正好相反,string的内容会初始化在bitset的右侧,因为bitset的低位在右侧 ?...返回bitset的位数,test(pos)返回某个位是否被置位,set(pos,v)将某个位置位为v,to_string(zero,one)将bitset转换回字符串string bitset也可以直接IO...正则表达式regex在构造的时候可以附加参数,例如icase参数会忽略大小写,basic参数将语法改为POSIX等等 正则表达式是一种简单的程序语言,一个regex对象被初始化或赋予新模式时才会被“编译...”,而且也可能发生编写错误甚至内存错误之类 正则表达式出现错误时会以regex_error的异常抛出,所以使用时需要try-catch 正则表达式的编译是非常慢的过程,所以应该避免创建不必要的表达式 正则表达式也有很多个其他的类型版本...,要注意没有递减操作,解引用迭代器可以得到最后一个匹配的结果,指向一个smatch对象,对smatch对象取其str成员可以得到匹配的字符串 匹配类型smatch中有prefix和suffix成员,可以取得当前匹配的前缀和后缀指针

    1K20

    C++的extern关键字知识点

    也就是说extern有两个作用,第一个,它与"C"一起用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是...C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样),为什么这么做呢,...()   {  cout << g_str << endl;   }    这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,但是我想说这样做非常糟糕,因为你由于无法在..., 如extern const char g_str[];     然后在原文件中别忘了定义:     const char g_str[] = "123456";      所以const单独使用时它就与...static相同,而extern一起合作的时候,它的特性就跟extern的一样了!

    1K40

    《Java性能权威指南》笔记----JIT编译

    (3)对于长时间运行的应用,首选server编译器,最好配合分层编译。 JavaJIT编译器版本 编译器的选择取决于JVM是32位还是64位,以及传递给JVM的编译器参数。 ?...降低编译阈值通常基于以下两种原因:     (1)减少应用热身的时间,     (2)使一些原本可能不被server编译编译的方法得以编译。...= null) { System.out.println("print " + str); } }     为什么进行方法内联?       ...大致原理:在未发生方法调用前,内联缓存是空的,发生第一次调用时,缓存记录下方法接收者的版本信息,以后再次调用该方法时,会比较版本信息,如果版本一致则可以继续使用这个内联,如果版本不一致则取消当前内联...例如:通过增加MaxInlineSize以便内联更多的方法,更多的方法在第一次调用时就会被内联,但是,方法只有经常被调用时才值得内联。

    1.2K10

    第 17 章 标准库特殊设施

    ; // 用 r在 test_str中查找 pattern匹配的子串 if (regex_search(test_str, results, r)) cout << results.str()...正则表达式是在运行时而非编译编译的,而正则表达式的编译是一个非常慢的操作。所以在实际编程中,应该尽量避免创建很多不必要的 regex对象。...解引用这个迭代器,则会得到一个 smatch对象。...如果正则表达式中的模式包含一个或多个子表达式时,得到的 smatch对象中还会包含多个 ssmatch对象,表示模式中每个子表达式的匹配信息。 对于多个子表达式,使用括号来进行分组隔开。...但是程序需要不同范围的随机数、随机浮点数或非均匀分布的数时,就需要程序员自己进行类型转换了,而这往往会引入非随机性。

    1.1K30

    【C++掌中宝】深入理解函数重载:概念、规则应用

    函数重载提高了代码的灵活性和可读性,使相同操作在不同上下文中可以使用统一的函数名,从而避免重复定义不同名字的函数。本文将深入探讨函数重载的概念、规则,编译器如何处理重载,以及使用中的注意事项。 1....; // 调用 print(string) return 0; } 在这个例子中,编译器会根据传递的参数类型,自动选择合适的 print 函数来执行。 2. 为什么需要函数重载?...比如说下面这个示例: //返回值不同不能作为重载条件,因为调用时无法区分 void fxx() {} int fxx() { return 0; } 因为对于有返回值的函数,返回值我可以不接收。...重载函数的调用匹配规则 调用重载函数时,编译器会按照以下顺序依次进行匹配: 精确匹配:参数类型声明的函数完全一致,参数匹配而不做转换,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针...如果多个函数符合匹配条件且优先级相同,编译器会报错,因为无法确定唯一的最佳匹配。

    15110

    第 17 章 标准库特殊设施

    ; // 用 r在 test_str中查找 pattern匹配的子串 if (regex_search(test_str, results, r)) cout << results.str()...正则表达式是在运行时而非编译编译的,而正则表达式的编译是一个非常慢的操作。所以在实际编程中,应该尽量避免创建很多不必要的 regex对象。...解引用这个迭代器,则会得到一个 smatch对象。...如果正则表达式中的模式包含一个或多个子表达式时,得到的 smatch对象中还会包含多个 ssmatch对象,表示模式中每个子表达式的匹配信息。 对于多个子表达式,使用括号来进行分组隔开。...但是程序需要不同范围的随机数、随机浮点数或非均匀分布的数时,就需要程序员自己进行类型转换了,而这往往会引入非随机性。

    74620

    extern关键字详解

    extern有两个作用 1.它与"C"一起用时,如: extern "C" void fun(int a, int b);告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++...(2)extern全局变量 如果在一个test1.h头文件中将全局变量的声明和定义放在一起, extern char g_str[] = "123456"; // 这个时候相当于没有extern 在两个...];这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,但是这样做非常糟糕,因为你由于无法在test2.cpp中使用#include "test1.h",那么test1...,以达到生成的目标程序更节省内存,执行效率更高,编译器在连接各个编译单元的时候,它会把相同内容的内存只拷贝一份,比如上面的"123456", 位于两个编译单元中的变量都是同样的内容,那么在连接的时候它在内存中就只会存在一份了...const char g_str[]; 然后在原文件中别忘了定义: const char g_str[] = "123456"; 所以const单独使用时它就与static相同,而extern一起合作的时候

    1.8K10

    【笔记】《C++Primer》—— 第19章:特殊工具技术

    否则返回结果会是指针的静态类型 typeid也会决定表达式是否会被求值,只有类型含有虚函数时才会对表达式进行求值 如果e是一个空指针,那么typeid会抛出一个bad_typeid异常 typeid返回的type_info类是编译器相关的...解决继承关系类的相等运算符问题,可以看到关键是我们不能确定两个对象的类型从而无法对比它们的成员。...来让编译器自己去推断成员的类型,也就是在需要传入可调用对象的地方改写为mem_fn(&Screen::testFunction)即可 还有一种方法就是老方法bind函数,即bind(&Screen::testFunction...C++函数一样,但是生成的代码有所差别,C++使用链接指示来指出那些非C++的函数 使用其他语言函数前要确保有权使用其他语言的编译器且当前的C++编译器是互相兼容的 链接指示也就是在函数的声明前写 extern..."Lang",其中Lang是目标语言的代号,例如C语言是C,需要指示多个函数时可以用大括号把函数都括在一起,这称为多重声明 多重声明可以包括头文件,而且链接指示可以嵌套,也就是此时头文件中的所有函数都会被当作另一种语言写的

    84940

    《C++Primer》第十九章

    编译器发现一条new表达式或者delete表达式后,将在程序中查找可供调用的operator函数: 如果被分配(释放)的对象是类类型,则编译器首先在类及其基类的作用域中查找 否则在全局作用域中查找...仅通过一个地址值调用时,定位new使用operator new(size_t, void*),这是以一个我们无法自定义的operator new版本,它只是简单地返回指针实参,然后由new表达式负责在指定的地址初始化对象以完成整个工作...一般来说,只要有可能我们应该尽量使用虚函数,操作被定义成虚函数时,编译器将根据对象的动态类型自动地选择正确的函数版本。 然而并非任何时候都能定义一个虚函数。...假设我们无法使用虚函数,那么可以使用一个RTTI运算符。另一方面,虚成员函数相比,使用RTTI运算符蕴涵着更多潜在的风险:程序员必须清楚地知道转换的目标类型并且必须检查类型转换是否被成功执行。...对象的值可能在程序的控制或检测之外被改变时,应该将该对象声明为volatile,告诉编译器不应对这样的对象进行优化。

    1.3K10

    如何理解Rust的核心特性(所有权、借用、生命周期)

    那rust为什么要引入所有权机制呢?原因在于,方便内存回收。如果一个堆空间的地址,只能保存在一个变量里面,那么这个变量出栈,无法再使用,那么不就代表这个堆空间就无法在程序内使用了吗?...这就是rust的内存回收策略了,它的编译开发者约定了这么一个规则——一个堆空间的地址,只能保存在一个值当中——如果我们不遵守这个规则,编译器就给我们报错,不给我们编译但如果我们遵守这个规则,编译器就很简单的判断出来了每一个空间要在什么时候回收...("{}", longest_str); }}可以看到a和b两个变量的生命周期显而易见不同,但是这代码是正确的。一个函数需要输入借用输出借用时,就必须显式的声明生命周期。...("{}", longest_str); }}这里,函数定义时的形参分别是str1和str2,调用时的实参是b和a,定义时,str1的生命周期更长,调用时,b的生命周期却更短。...使用时,a和b的生命周期都不短于longest_str的生命周期,调用时遵守了生命周期原则。尽管双方不一致,但是前者不会影响后者,前者仅仅只是帮编译器在定义时做校验,所以不会报错。

    97650

    C语言中的宏定义

    一个函数被调用时编译器会检查每一个参数来确认它们是否是正确的类型。如果不是,或者将参数转换成正确的类型,或者由编译器产生一个出错信息。预处理器不会检查宏参数的类型,也不会进行类型转换。...如我们所见,MAX的参数有副作用时无法正常工作。一种解决方法是用MAX宏来写一个max函数。遗憾的是,往往一个max函数是不够的。...解决的办法是定义一个宏,并使它展开后成为max函数的定义。宏会有唯一的参数type,它表示形式参数和返回值的类型。这里还有个问题,如果我们是用宏来创建多个max函数,程序将无法编译。...ECHO宏时,一定要加分号: ECHO(str); /* becomes do { gets(str); puts(str); } while (0); */ 为什么在宏定义时需要使用...__cplusplus 标准c++一致的编译器把它定义为一个包含至少6为的数值。标准c++不一致的编译器将使用具有5位或更少的数值。

    6.4K10

    Java语法糖(二)

    成员内部类不同的是,且仅当局部内部类出现在非静态的环境(如非静态方法)中时,才会拥有对外部类实例的引用。出现在静态环境中,内部类实例没有对外部类实例的引用,也不拥有外围类任何静态成员。     ...对于局部变量str,被final修饰意味着str是一个常量,在编译期间就可以确定并放入常量池,编译器默认为内部类创建一个局部变量的拷贝,通过拷贝去常量池访问就可以了,看这条语句ldc <String "...总的来说,如果局部变量的值在编译期间就可以确定(str),则直接在匿名内部类(局部内部类)中创建一份拷贝;如果局部变量的值无法编译期间确定(paramStr),则通过构造器传参的方式对拷贝进行初始化。...常见用法:作为公有的辅助类,仅它与外围类一起使用时才有意义。     Map中Entry为私有静态内部类,Entry是外部类的一个组件。...3、内部类可以实现更好的封装,使类之间的关系更加紧密。   如何选择使用哪种内部类?

    40430
    领券