boost在lambda表达式中调用占位符参数的成员函数的方法

boost中提供了lambda表达式的用法,但是lambda表达式的功能还不是很强大,在其中只能对lambda的占位符参数_1等使用最基本的操作符,如+-*/,可是很多时候如果传入的占位符参数是一个对象指针的话,我们可能想要调用这个类的成员函数。

我在开发中遇到了这个问题,需要在stl的算法中传入一个函数来调用对象的比较函数,因为感觉这样太麻烦,还需要重新定义一个函数,所以想起了lambda表达式,c++11的lambda表达式我倒是没试过,可是受项目开发环境所限,只能选择boost。但是我用的时候才发现,boost的lambda表达式居然不支持在占位符参数上调用函数,在网上找了很久也没有发现相关的文章。最后在boost的官方文档中找到了解决方法,可是这种方案只能简单的调用函数,无法对函数的返回值做任何操作,但是有时候可能要对函数返回值做一些比较之类的,就不行了。其使用这种方法调用函数纯属多此一举,使用bind可以达成同样的功能,而且bind可以识别出智能指针。

这是boost官方实例,注意,使用_1时一定要限定boost::lambda命名空间,不然会编译错误。

struct B { int foo(int); };
B* b = new B();
  ...
(b ->* &B::foo)         // returns a delayed call to b->foo
                        // a function argument list must follow
(b ->* &B::foo)(1)      // ok, calls b->foo(1)

(_1 ->* &B::foo)(b);    // returns a delayed call to b->foo,
                        // no effect as such
(_1 ->* &B::foo)(b)(1); // calls b->foo(1)

最后只能找其他方法,最后终于被我想到了一种代替的方法,但是还是有一些缺陷,但是做一些简单的调用还是可以的,在此分享出来,也算填补一个空白。

其核心思想就是在lambda表达式中使用bind来绑定占位符参数做一个调用来完成调用函数的功能,但是还是有些缺陷,后面会讲。

看代码

#include <iostream>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/function.hpp>

class A
{
public:
    int a;
    int b;
  virtual int  test()
  {
      std::cout<<"A"<<std::endl;
      return 1;
  }
};

class B:public A
{
    int c;
    virtual int test()
    {
        std::cout<<"B"<<std::endl;
        return 2;
    }
};

void test(A* p)
{
    p->test();
}

int main()
{
//boost 官方示例用法,但是调用函数的返回值不能在进行任何运算,否则会编译错误,坑啊
   std::cout<< ((boost::lambda::_1 ->* &A::test)) (new B)();
    //智能指针,没错,bind很强大,能绑定虚函数,甚至能识别出智能指针
    boost::shared_ptr<A>o= boost::make_shared<B>();
    //在lambda中使用bind调用占位符参数的test方法
    std::cout<<( (boost::bind(&A::test,_1)<=2)(o) );
    //这就是我说的缺陷了,如果要对bind表达式的结果进行运算,只能把bind表达式放在运算符左边,巨坑啊
    //std::cout<<((2>boost::bind(&A::test,_1))(o));
    //这是另一个缺陷,如果要对bind表达式的结果进行运算,只支持比较操作符,就是<、>、==等比较操作符,
    //不支持+、-、*、/等运算符,坑到底啊
    //std::cout<<((boost::bind(&A::test,_1)+1)(o));

    getchar();

}

虽然找到了替代用法,但是还是有很多限制,只能把bind表达式放在运算符左边,只支持比较操作符,但在一些简单的比较场合,比如stl算法,已经够用了,总比以前好点。

由于本人水平有限,难免会有些考虑不周之处,敬请指证!仅以此文以表我对这个问题的看法,希望能和大家交流交流,谢谢 !

boost在lambda表达式中调用占位符参数的成员函数的方法,布布扣,bubuko.com

时间: 05-24

boost在lambda表达式中调用占位符参数的成员函数的方法的相关文章

Java C# C语言中的占位符

一般拼接一段字符串在编程中是很常见的事,下面简单做个总结: 什么是占位符?占位符就是先占住一个固定的位置,等着你再往里面添加内容的符号. 1.Java中处理方法: package com.amos; import java.text.MessageFormat; /** * Created by amosli on 14-7-24. */ public class Test { public static void main(String args[]) { //拼接一段string 常用的方法

c++11模拟boost中元占位符

准备实现meta programming的fold函数,发现自己缺少占位符实现,这样传入fold的transform op类(元函数)都不得不另外写个外覆类,其实我觉得没啥不好,简单直接,说实话干扰什么的没那么严重,一个功能块里能用fold的地方能有几次?但动了占位符这个念头,就想尝试实现一下. 看一下实际情景: template<typename TList, typename Init, class TransformOp> struct fold_s {}; 我们可能会希望把push_b

SpringMVC(七) RequestMapping 路径中带占位符的URL

使用方法:在@RequestMapping("/delete/{id}")中,通过{id}带入pathvariable,然后在方法中,通过@PathVariable("变量名称") Iteger id 的方式引入占位符. 控制器代码: package com.tiekui.springmvc.handlers; import org.springframework.stereotype.Controller; import org.springframework.w

在Lambda表达式中使用循环变量

在C#5.0之前的版本中,如果在foreach循环中的lambda使用循环变量,那么你会发现一些意想不到的现象,例子如下: var integers = new List<int> { 1, 2, 3, 4 }; var actions = new List<Action>(); foreach (var integer in integers) { actions.Add(() => Console.WriteLine(integer)); } actions.ForEac

Lambda表达式中的表达式lambda和语句lambda区别

Lambda表达式可分为表达式lambda和语句lambda 表达式lambda:表达式位于 => 运算符右侧的lambda表达式称为表达式lambda (input parameters) => expression //表达式lambda 例如 (x, y) => x == y 语句lambda:=> 运算符右侧是一个语句块,语句包含在大括号中 (input parameters) => {statement;} //语句lambda 例如: (x, y) => {

SQl语句中使用占位符的优点

1.增加SQL代码可读性2.占位符可以预先编译,提高执行效率3.防止SQL注入4用占位符的目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少 绑定变量是Oracle解决硬解析的首要利器,能解决OLTP系统中library cache的过度耗用以提高性能 绑定变量是Oracle解决硬解析的首要利器,能解决OLTP系统中library cache的过度耗用以提高性能.然刀子磨的太快,使起来锋利,却容易折断.凡事皆有利弊二性,因地制宜,因时制宜,全在如何权衡而已.本文讲述了绑定变量

oracle pl/sql之在java中调用带有输入输出参数的oracle存储过程

只需注意一点输出参数是用CallableStatement里面的registerOutParameter方法注册进去 存储过程: import java.sql.CallableStatement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.Types; //在java中

[Java] 继承中,父类被覆盖的成员变量、方法的可访问性

在 Java 的继承机制里,在子类内部,可以访问父类被覆盖的变量和方法:在子类外部,可以访问父类的被覆盖变量,但是不能访问父类的被覆盖方法. 父类中被覆盖的方法不能在外部被方法,这是出于封装的考虑. 例子: Super, 父类,拥有一个成员变量 x ,和成员方法 doSomething(). Point,继承 Super, 但覆盖了 Super 的 x 和 doSomething(),拥有自己的同名成员成员 x 和 doSomething(). StaticDemo1, 演示在继承中,在内部,可

spring 的 PropertyPlaceholderConfigurer读取的属性怎么访问 (java访问方式,不是xml中的占位符哦)

<!-- 属性文件 --> <bean id="configs" class="org.springframework.beans.factory.config.PropertiesFactoryBean">      <property name="locations">          <list>                <value>classpath:spring/jd